

# 引用其他 CloudFormation 堆栈中的资源输出
<a name="walkthrough-crossstackref"></a>

本演练演示了如何在一个堆栈中引用另一个 CloudFormation 堆栈的输出，以创建更多模块化和可重复使用的模板。

您可以在单独的堆栈中创建相关的 AWS 资源，而不是在单个堆栈中包含所有资源。然后，您可以引用其他堆栈中的所需资源输出。通过限制对输出的跨堆栈引用，您可以控制由其他堆栈引用的堆栈部分。

例如，您可以将一个带 VPC、安全组和子网的网络堆栈用于公有 Web 应用程序，并且有一个单独的公有 Web 应用程序堆栈。为确保 Web 应用程序能使用网络堆栈中的安全组和子网，可以创建一个使 Web 应用程序堆栈能够引用网络堆栈中的资源输出的跨堆栈引用。借助跨堆栈引用，Web 应用程序堆栈的所有者无需创建或维护联网规则或资产。

要创建跨堆栈引用，可使用 `Export` 输出字段标记要导出的资源输出的值。然后，使用 `Fn::ImportValue` 内置函数导入该值。有关更多信息，请参阅 [获取从已部署的 CloudFormation 堆栈导出的输出](using-cfn-stack-exports.md)。

**注意**  
CloudFormation 是一项免费服务。但是，对于堆栈中包含的 AWS 资源，您需要按各自的现有费率付费。有关 AWS 定价的更多信息，请参阅[每种产品的详细信息页](https://aws.amazon.com/)。

**Topics**
+ [使用示例模板创建网络堆栈](#walkthrough-crossstackref-create-vpc-stack)
+ [使用示例模板创建 Web 应用程序堆栈](#walkthrough-crossstackref-create-ec2-stack)
+ [验证堆栈的运行是否符合设计](#walkthrough-crossstackref-verify)
+ [排查 AMI 映射问题](#walkthrough-crossstackref-troubleshooting-ami)
+ [清除资源](#walkthrough-crossstackref-clean-up)

## 使用示例模板创建网络堆栈
<a name="walkthrough-crossstackref-create-vpc-stack"></a>

在开始此演练之前，请确认您具有使用以下所有服务的 IAM 权限：Amazon VPC、Amazon EC2 和 CloudFormation。

网络堆栈包含您将在 Web 应用程序堆栈中使用的 VPC、安全组和子网。除了这些资源之外，网络堆栈还将创建互联网网关和路由表来实现公共访问。

您必须先创建此堆栈，然后才能创建 Web 应用程序堆栈。如果先创建 Web 应用程序堆栈，则它没有安全组或子网。

该堆栈模板可通过以下 URL 获取：[https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleNetworkCrossStack.template](https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleNetworkCrossStack.template)。要查看堆栈将创建的资源，请选择该链接，这将打开模板。在 `Outputs` 部分中，您可看到示例模板导出的联网资源。如果您从其他堆栈导出联网资源，则已导出资源的名称将以堆栈的名称为前缀。当用户导入联网资源时，他们可指定从中导入资源的堆栈。

**创建网络堆栈**

1. 登录到 AWS 管理控制台 并打开 CloudFormation 控制台 [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 在**堆栈**页面，选择右上角的**堆栈**，然后选择**使用新资源（标准）**。

1. 选择**模板已准备就绪**，然后在**指定模板**部分选择 **Amazon S3 URL**。

1. 在 **Amazon S3 URL** 中，粘贴以下 URL：**https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleNetworkCrossStack.template**。

1. 选择**下一步**。

1. 对于 **Stack name (堆栈名称)**，键入 **SampleNetworkCrossStack**，然后选择 **Next (下一步)**。
**注意**  
记录此堆栈的名称。您在启动 Web 应用程序堆栈时需要此堆栈名称。

1. 选择**下一步**。在本演练中，您无需添加标记或指定高级设置。

1. 确保堆栈名称和模板 URL 正确，然后选择 **Create stack (创建堆栈)**。

   CloudFormation 可能需要几分钟的时间创建堆栈。请耐心等待，直到成功创建所有资源，然后再继续创建 Web 应用程序堆栈。

1. 要监控进度，可查看堆栈事件。有关更多信息，请参阅 [监控堆栈进度](monitor-stack-progress.md)。

## 使用示例模板创建 Web 应用程序堆栈
<a name="walkthrough-crossstackref-create-ec2-stack"></a>

Web 应用程序堆栈将创建一个使用网络堆栈中的安全组和子网的 EC2 实例。

您必须在网络堆栈所在的同一 AWS 区域中创建该堆栈。

该堆栈模板可通过以下 URL 获取：[https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template](https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template)。要查看堆栈将创建的资源，请选择该链接，这样会打开模板。在 `Resources` 部分中，查看 EC2 实例的属性。您可查看如何使用 `Fn::ImportValue` 函数从其他堆栈导入联网资源。

**创建 Web 应用程序堆栈**

1. 在**堆栈**页面，选择右上角的**创建堆栈**，然后选择**使用新资源（标准）**。

1. 选择**模板已准备就绪**，然后在**指定模板**部分选择 **Amazon S3 URL**。

1. 在 **Amazon S3 URL** 中，粘贴以下 URL：**https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template**。

1. 选择**下一步**。

1. 对于 **Stack name**，键入 **SampleWebAppCrossStack**。在 **Parameters** 部分中，让 **NetworkStackName** 参数使用默认值，然后选择 **Next**。

   示例模板使用参数值指定要从中导入值的堆栈。

1. 选择**下一步**。在本演练中，您无需添加标记或指定高级设置。

1. 确保堆栈名称和模板 URL 正确，然后选择 **Create stack (创建堆栈)**。

   CloudFormation 可能需要几分钟的时间创建堆栈。

## 验证堆栈的运行是否符合设计
<a name="walkthrough-crossstackref-verify"></a>

创建该堆栈后，查看其资源并记下实例 ID。有关查看堆栈资源的更多信息，请参阅[从 CloudFormation 控制台查看堆栈信息](cfn-console-view-stack-data-resources.md)。

要验证实例的安全组和子网，请在 [Amazon EC2 控制台](https://console.aws.amazon.com/ec2/)中查看实例的属性。如果实例使用 `SampleNetworkCrossStack` 堆栈中的安全组和子网，则表示您已成功创建跨堆栈引用。

使用控制台可查看堆栈输出和示例网站 URL 以验证 Web 应用程序是否正在运行。有关更多信息，请参阅 [从 CloudFormation 控制台查看堆栈信息](cfn-console-view-stack-data-resources.md)。

## 排查 AMI 映射问题
<a name="walkthrough-crossstackref-troubleshooting-ami"></a>

如果您收到 `Template error: Unable to get mapping for AWSRegionArch2AMI::[region]::HVM64` 错误，则该模板不包含您在 AWS 区域的 AMI 映射。我们建议不要更新映射，而是使用 Systems Manager 公共参数动态引用最新的 AMI：

1. 将 `SampleWebAppCrossStack` 模板下载到您的本地计算机，下载网址为：[https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template](https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template)。

1. 删除整个 `AWSRegionArch2AMI` 映射部分。

1. 添加以下 Systems Manager 参数：

   ```
   "LatestAmiId": {
     "Description": "The latest Amazon Linux 2 AMI from the Parameter Store",
       "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
       "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
     }
   ```

1. 替换现有的 `ImageId` 引用：

   ```
   "ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" } , "HVM64" ] }, 
   ```

   借助:

   ```
   "ImageId": { "Ref": "LatestAmiId" },
   ```

   此参数会自动解析为堆栈部署区域的最新 Amazon Linux 2 AMI。

   对于其他 Linux 发行版，请使用相应的参数路径。有关公共参数的更多信息，请参阅《AWS Systems Manager 用户指南》**中的[发现 Parameter Store 中的公有参数](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)。

1. 将修改后的模板上传到您账户中的 S3 存储桶：

   ```
   aws s3 cp SampleWebAppCrossStack.template s3://amzn-s3-demo-bucket/
   ```

1. 创建堆栈时，请指定您的 S3 模板 URL，不要使用示例 URL。

## 清除资源
<a name="walkthrough-crossstackref-clean-up"></a>

为了确保不因任何不必要的服务而产生费用，请删除堆栈。

**删除堆栈**

1. 在 CloudFormation 控制台中，选择 `SampleWebAppCrossStack` 堆栈。

1. 选择 **Actions**)（操作），然后选择 **Delete Stack**（删除堆栈）。

1. 在确认消息中，选择 **Delete (删除)**。

1. 在删除堆栈后，对 `SampleNetworkCrossStack` 堆栈重复相同的步骤。
**注意**  
等到 CloudFormation 完全删除 `SampleWebAppCrossStack` 堆栈。如果 EC2 实例仍在 VPC 中运行，则 CloudFormation 不会删除 `SampleNetworkCrossStack` 堆栈中的 VPC。