

# CloudFormation 入门
<a name="GettingStarted"></a>

您可以通过 AWS 管理控制台，使用示例模板创建一个堆栈来学习使用 CloudFormation，这有助您了解堆栈创建的基础知识。*模板*是一个用于定义堆栈中所有资源的文本文件。*堆栈*是 CloudFormation 模板的部署。您可以从单个模板创建多个堆栈。每个堆栈都包含可作为单个单元管理的 AWS 资源集合。

CloudFormation 是一种免费服务；但是，您需要按各种资源的现行价格，为堆栈使用的 AWS 资源付费。有关 AWS 定价的更多信息，请转至 [http://aws.amazon.com](https://aws.amazon.com/) 上每种产品的详细信息页面。

**视频：CloudFormation 入门**  
以下视频介绍如何通过 AWS 管理控制台创建 CloudFormation 堆栈。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/1h-GPXQrLZw?si=MYHlJvBkE3DspKcL/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/1h-GPXQrLZw?si=MYHlJvBkE3DspKcL)


**Topics**
+ [

# CloudFormation 的工作原理
](cloudformation-overview.md)
+ [

# 注册 AWS 账户
](cfn-sign-up-for-aws.md)
+ [

# 创建第一个堆栈
](gettingstarted.walkthrough.md)

# CloudFormation 的工作原理
<a name="cloudformation-overview"></a>

本主题说明了 CloudFormation 的工作原理，并介绍了在使用此服务时需要了解的关键概念。

**Topics**
+ [

## 重要概念
](#cfn-whatis-concepts)
+ [

## CloudFormation 的工作原理
](#cfn-whatis-howdoesitwork)
+ [

## CloudFormation 入门方式
](#ways-to-get-started)

## 重要概念
<a name="cfn-whatis-concepts"></a>

在使用 CloudFormation 时，您将使用*模板*和*堆栈*。您创建模板来描述 AWS 资源及其属性。当您创建堆栈时，CloudFormation 会配置模板中描述的资源。

**Topics**
+ [

### 模板
](#cfn-concepts-templates)
+ [

### 堆栈
](#cfn-concepts-stacks)
+ [

### 更改集
](#cfn-concepts-change-sets)

### 模板
<a name="cfn-concepts-templates"></a>

CloudFormation 模板是一个 JSON 或 YAML 格式的文本文件。您可使用任何扩展名（如 `.yaml`、`.json`、`.template` 或 `.txt`）保存这些文件。CloudFormation 使用这些模板作为构建 AWS 资源的蓝图。例如，在模板中，您可描述 Amazon EC2 实例，如实例类型、AMI ID、块储存设备映射和其 Amazon EC2 密钥对名称。当您创建堆栈时，还可以指定 CloudFormation 用来创建模板中描述的任何项的模板。

例如，如果您使用以下模板创建堆栈，则 CloudFormation 将使用 `ami-0ff8a91507f77f867` AMI ID、`t2.micro` 实例类型、`testkey` 密钥对名称和 Amazon EBS 卷来配置实例。

#### YAML
<a name="t2-micro-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: A sample template
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0ff8a91507f77f867
      InstanceType: t2.micro
      KeyName: testkey
      BlockDeviceMappings:
        - DeviceName: /dev/sdm
          Ebs:
            VolumeType: io1
            Iops: 200
            DeleteOnTermination: false
            VolumeSize: 20
```

#### JSON
<a name="t2-micro-example.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "A sample template",
    "Resources": {
        "MyEC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": "ami-0ff8a91507f77f867",
                "InstanceType": "t2.micro",
                "KeyName": "testkey",
                "BlockDeviceMappings": [
                    {
                        "DeviceName": "/dev/sdm",
                        "Ebs": {
                            "VolumeType": "io1",
                            "Iops": 200,
                            "DeleteOnTermination": false,
                            "VolumeSize": 20
                        }
                    }
                ]
            }
        }
    }
}
```

您还可以在单个模板中指定多种资源并将这些资源配置为结合使用。例如，您可以修改上一个模板来包含一个弹性 IP 地址（EIP）并将其与 Amazon EC2 实例相关联，如以下示例所示：

#### YAML
<a name="multiple-resources-single-template.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: A sample template
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0ff8a91507f77f867
      InstanceType: t2.micro
      KeyName: testkey
      BlockDeviceMappings:
        - DeviceName: /dev/sdm
          Ebs:
            VolumeType: io1
            Iops: 200
            DeleteOnTermination: false
            VolumeSize: 20
  MyEIP:
    Type: AWS::EC2::EIP
    Properties:
      InstanceId: !Ref MyEC2Instance
```

#### JSON
<a name="multiple-resources-single-template.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "A sample template",
    "Resources": {
        "MyEC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": "ami-0ff8a91507f77f867",
                "InstanceType": "t2.micro",
                "KeyName": "testkey",
                "BlockDeviceMappings": [
                    {
                        "DeviceName": "/dev/sdm",
                        "Ebs": {
                            "VolumeType": "io1",
                            "Iops": 200,
                            "DeleteOnTermination": false,
                            "VolumeSize": 20
                        }
                    }
                ]
            }
        },
        "MyEIP": {
            "Type": "AWS::EC2::EIP",
            "Properties": {
                "InstanceId": {
                    "Ref": "MyEC2Instance"
                }
            }
        }
    }
}
```

之前的模板以 Amazon EC2 实例为中心；但 CloudFormation 模板还具有其他功能，可利用这些功能来构建复杂的资源集并在许多环境中重新使用这些模板。例如，您可添加输入参数，其值是在创建 CloudFormation 堆栈时指定的。换句话说，您可在创建堆栈而不是创建模板时指定一个值 (如实例类型)，以便在不同的情况下更轻松地重新使用模板。

### 堆栈
<a name="cfn-concepts-stacks"></a>

在您使用 CloudFormation 时，可将相关资源作为一个称为堆栈的单元进行管理。您可通过创建、更新和删除堆栈来创建、更新和删除一组资源。堆栈中的所有资源均由堆栈的 CloudFormation 模板定义。假设您创建了一个模板，它包括自动扩缩组、Elastic Load Balancing 负载均衡器和 Amazon Relational Database Service (Amazon RDS) 数据库实例。要创建这些资源，您可通过提交已创建的模板来创建堆栈，CloudFormation 将会为您配置所有这些资源。

### 更改集
<a name="cfn-concepts-change-sets"></a>

如果您需要更改堆栈中运行的资源，则可更新堆栈。在更改资源之前，您可以生成一个更改集，这是建议进行的更改的摘要。利用更改集，您可以在实施更改之前，了解更改可能会对运行的资源 (特别是关键资源) 造成的影响。

例如，如果您更改 Amazon RDS 数据库实例的名称，则 CloudFormation 将创建新数据库并删除旧数据库。除非您已经对旧数据库中的数据进行备份，否则您将丢失该数据。如果您生成了更改集，则将了解更改会导致数据库被替换，而您可以先做出相应的计划，然后再更新堆栈。

## CloudFormation 的工作原理
<a name="cfn-whatis-howdoesitwork"></a>

使用 CloudFormation 创建堆栈时，CloudFormation 会向 AWS 发出基础服务调用以预置和配置模板中描述的资源。您需要有创建这些资源的权限。例如，要使用 CloudFormation 创建 EC2 实例，您需要具有创建实例的权限。您可以使用 [AWS Identity and Access Management](https://docs.aws.amazon.com/IAM/latest/UserGuide/)（IAM）来管理这些权限。

CloudFormation 进行的调用全部由您的模板声明。例如，假设您有一个描述带 `t2.micro` 实例类型的 EC2 实例的模板。当您使用该模板创建堆栈时，CloudFormation 将调用 Amazon EC2 创建实例 API 并将该实例类型指定为 `t2.micro`。以下示意图归纳了用于创建堆栈的 CloudFormation 工作流程。

![\[保存在本地或存储桶中的已创建或现有模板，用于创建堆栈。\]](http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/images/create-stack-diagram.png)


**创建堆栈**

1. 使用文本编辑器创建 JSON 或 YAML 格式的 CloudFormation 模板。CloudFormation 模板描述了您所需的资源及其设置。使用 [基础架构编辑器](infrastructure-composer-for-cloudformation.md) 可视化显示和验证模板。这有助您确保模板结构正确，没有语法错误。有关更多信息，请参阅 [使用 CloudFormation 模板](template-guide.md)。

1. 您可将模板保存在本地或 Amazon S3 存储桶中。

1. 通过指定模板文件的位置（例如，本地计算机上的路径或 Amazon S3 URL）来创建 CloudFormation 堆栈。如果模板包含参数，则可在创建堆栈时指定输入值。利用参数，您可以将值传入模板，以便能在创建堆栈时自定义资源。
**注意**  
如果您指定本地存储的模板文件，CloudFormation 会将其上传到您 AWS 账户中的 S3 桶。CloudFormation 为您上传模板文件的每个区域创建一个桶。具有您 AWS 账户中 Amazon Simple Storage Service（Amazon S3）权限的任何人均可访问桶。如果 CloudFormation 创建的存储桶已存在，则将模板添加到该存储桶。  
您可通过手动将模板上传到 Amazon S3 来使用您自己的存储桶并管理其权限。之后，当您创建或更新堆栈时，请指定模板文件的 Amazon S3 URL。

所有资源创建完毕后，CloudFormation 会报告已创建您的堆栈。然后，您可以开始使用堆栈中的资源。如果堆栈创建失败，则 CloudFormation 会通过删除已创建的资源来回滚您的更改。

### 使用更改集更新堆栈
<a name="updating-stack-with-change-sets"></a>

在需要更新堆栈的资源时，您可以修改堆栈的模板。您不需要创建新堆栈和删除旧堆栈。要更新堆栈，请提交修改的原始堆栈模板版本和/或不同的输入参数值以创建一个更改集。CloudFormation 将修改的模板与原始模板进行比较并生成一个更改集。更改集列出了建议的更改。在审核更改后，您可以启动更改集以更新堆栈，也可以创建新的更改集。以下示意图概述了用于更新堆栈的工作流程。

![\[在执行更改集以更新堆栈之前，使用更改集来查看修改后的值的模板。\]](http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/images/update-stack-diagram.png)


**使用更改集更新堆栈**

1. 您可以使用[基础架构编辑器](infrastructure-composer-for-cloudformation.md)或文本编辑器来修改 CloudFormation 堆栈模板。有关更多信息，请参阅 [更新堆栈模板](using-cfn-updating-stacks-get-template.md)。

   更新模板时，应注意更新可能会导致中断。根据您所更新的资源和属性，更新可能会中断或者甚至替换现有资源。有关更多信息，请参阅 [理解堆栈资源的更新行为](using-cfn-updating-stacks-update-behaviors.md)。

1. 您可在本地或在 S3 存储桶中保存 CloudFormation 模板。

1. 通过指定要更新的堆栈和修改后模板的位置 (例如本地计算机上的路径或 Amazon S3 URL) 来创建更改集。有关创建更改集的更多信息，请参阅[使用更改集更新 CloudFormation 堆栈](using-cfn-updating-stacks-changesets.md)。
**注意**  
如果您指定存储在本地计算机上的模板，则 CloudFormation 自动将模板上传到 AWS 账户 中的 S3 桶。

1. 查看更改集以检查 CloudFormation 是否将执行预期更改。例如，检查 CloudFormation 是否将替换任何关键堆栈资源。您可以创建所需数量的更改集，直到您包含所需的更改。
**重要**  
更改集并不指示您的堆栈更新是否将成功。例如，更改集不会检查是否将超出账户[配额](cloudformation-limits.md)、是否在更新不支持更新的资源或者是否[权限](control-access-with-iam.md)不足而无法修改资源，这些都可能导致堆栈更新失败。

1. 启动要应用于堆栈的更改集。CloudFormation 仅更新您修改的资源以更新堆栈，并发出已成功更新堆栈的信号。如果堆栈更新失败，则 CloudFormation 将回滚更改以将堆栈还原到上一个已知工作状态。

## CloudFormation 入门方式
<a name="ways-to-get-started"></a>

要使用控制台创建 hello world CloudFormation 堆栈，请参阅[创建第一个堆栈](gettingstarted.walkthrough.md)。

如需指导学习，请尝试 [CloudFormation 入门](https://catalog.us-east-1.prod.workshops.aws/workshops/df7f72cf-4f10-4664-acb6-b30dc8d4bcf0/en-US)讲习会，其提供模板开发的实践经验。

# 注册 AWS 账户
<a name="cfn-sign-up-for-aws"></a>

在您注册 AWS 时，将为您的 AWS 账户 自动注册 AWS 中的所有服务，包括 CloudFormation。如果您已有 AWS 账户，请跳到下一个主题。如果您还没有AWS 账户，请使用以下流程创建。

## 注册 AWS 账户
<a name="sign-up-for-aws"></a>

如果您还没有 AWS 账户，请完成以下步骤来创建一个。

**注册 AWS 账户**

1. 打开 [https://portal.aws.amazon.com/billing/signup](https://portal.aws.amazon.com/billing/signup)。

1. 按照屏幕上的说明操作。

   在注册时，将接到电话或收到短信，要求使用电话键盘输入一个验证码。

   当您注册 AWS 账户 时，系统将会创建一个 AWS 账户根用户**。根用户有权访问该账户中的所有 AWS 服务 和资源。作为最佳安全实践，请为用户分配管理访问权限，并且只使用根用户来执行[需要根用户访问权限的任务](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks)。

注册过程完成后，AWS 会向您发送一封确认电子邮件。在任何时候，您都可以通过转至 [https://aws.amazon.com/](https://aws.amazon.com/) 并选择**我的账户**来查看当前的账户活动并管理您的账户。

## 创建具有管理访问权限的用户
<a name="create-an-admin"></a>

注册 AWS 账户 后，请保护好您的 AWS 账户根用户，启用 AWS IAM Identity Center，并创建一个管理用户，以避免使用根用户执行日常任务。

**保护您的 AWS 账户根用户**

1.  选择**根用户**并输入您的 AWS 账户 电子邮件地址，以账户拥有者身份登录 [AWS 管理控制台](https://console.aws.amazon.com/)。在下一页上，输入您的密码。

   要获取使用根用户登录方面的帮助，请参阅《AWS 登录 用户指南》**中的 [Signing in as the root user](https://docs.aws.amazon.com/signin/latest/userguide/console-sign-in-tutorials.html#introduction-to-root-user-sign-in-tutorial)。

1. 为您的根用户启用多重身份验证（MFA）。

   有关说明，请参阅《IAM 用户指南》**中的[为 AWS 账户 根用户启用虚拟 MFA 设备（控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/enable-virt-mfa-for-root.html)。

**创建具有管理访问权限的用户**

1. 启用 IAM Identity Center。

   有关说明，请参阅**《AWS IAM Identity Center 用户指南》中的 [Enabling AWS IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-set-up-for-idc.html)。

1. 在 IAM Identity Center 中，为用户授予管理访问权限。

   有关如何使用 IAM Identity Center 目录 作为身份源的教程，请参阅**《AWS IAM Identity Center 用户指南》中的 [Configure user access with the default IAM Identity Center 目录](https://docs.aws.amazon.com//singlesignon/latest/userguide/quick-start-default-idc.html)。

**以具有管理访问权限的用户身份登录**
+ 要使用您的 IAM Identity Center 用户身份登录，请使用您在创建 IAM Identity Center 用户时发送到您的电子邮件地址的登录 URL。

  要获取使用 IAM Identity Center 用户登录方面的帮助，请参阅《AWS 登录 用户指南》**中的 [Signing in to the AWS access portal](https://docs.aws.amazon.com/signin/latest/userguide/iam-id-center-sign-in-tutorial.html)。

**将访问权限分配给其他用户**

1. 在 IAM Identity Center 中，创建一个权限集，该权限集遵循应用最低权限的最佳做法。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-started-create-a-permission-set.html)。

1. 将用户分配到一个组，然后为该组分配单点登录访问权限。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Add groups](https://docs.aws.amazon.com//singlesignon/latest/userguide/addgroups.html)。

**注意**  
有关如何管理谁有权访问哪些功能的更多信息，请参阅 [使用 AWS Identity and Access Management 控制 CloudFormation 访问权限](control-access-with-iam.md)。

# 创建第一个堆栈
<a name="gettingstarted.walkthrough"></a>

本文演示使用 AWS 管理控制台 创建第一个 CloudFormation 堆栈的过程。学习本教程后，您将会了解如何配置基础 AWS 资源、监控堆栈事件和生成输出。

在本示例中，CloudFormation 模板采用 YAML 格式编写。YAML 是一种人类可解读的格式，广泛用于将基础架构定义为代码。您对 CloudFormation 的了解越来越多后，可能还会遇到其他 JSON 格式的模板，但是本教程选择使用 YAML，因为它的可读性好。

**注意**  
CloudFormation 使用免费，但您需要为自己创建的 Amazon EC2 和 Amazon S3 资源付费。如果您不熟悉 AWS，可以利用[免费套餐](https://aws.amazon.com/free/)来最大限度地降低或避免在学习过程产生费用。

**Topics**
+ [

## 先决条件
](#getting-started-prerequisites)
+ [

## 使用控制台创建 CloudFormation 堆栈
](#getting-started-create-stack)
+ [

## 监控堆栈创建
](#getting-started-monitor-stack-creation)
+ [

## 测试 Web 服务器
](#getting-started-test-web-server)
+ [

## 问题排查
](#getting-started-troubleshooting)
+ [

## 清理
](#getting-started-clean-up)
+ [

## 后续步骤
](#getting-started-next-steps)

## 先决条件
<a name="getting-started-prerequisites"></a>
+ 您必须具有对 AWS 账户的访问权限，且该账户需要拥有有权使用 Amazon EC2、Amazon S3 和 CloudFormation 的 IAM 用户或角色，或者拥有管理用户访问权限。
+ 必须拥有可访问互联网的虚拟私有云（VPC）。本演练模板需要默认 VPC，新版本 AWS 账户自动附带该默认 VPC。如果您没有默认 VPC，或者已将其删除，请参阅本主题中的疑难解答章节，了解其他解决方案。

## 使用控制台创建 CloudFormation 堆栈
<a name="getting-started-create-stack"></a>

**使用控制台创建 Hello world CloudFormation 堆栈**

1. 打开 [ CloudFormation 控制台](https://console.aws.amazon.com/cloudformation/)。

1. 选择**创建堆栈**。

1. 在**创建堆栈**页面上，选择**从基础架构编辑器构建**，然后选择**在基础架构编辑器中创建**。这会将您转至 CloudFormation 控制台模式下的基础架构编辑器，您可以在其中上传和验证示例模板。

1. 要创建和验证示例模板，请执行以下操作：

   1. 选择**模板**。然后，将下列 CloudFormation 模板复制粘贴到模板编辑器：

      ```
      AWSTemplateFormatVersion: 2010-09-09
      Description: CloudFormation Template for WebServer with Security Group and EC2 Instance
      
      Parameters:
        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'
      
        InstanceType:
          Description: WebServer EC2 instance type
          Type: String
          Default: t2.micro
          AllowedValues:
            - t3.micro
            - t2.micro
          ConstraintDescription: must be a valid EC2 instance type.
          
        MyIP:
          Description: Your IP address in CIDR format (e.g. 203.0.113.1/32).
          Type: String
          MinLength: '9'
          MaxLength: '18'
          Default: 0.0.0.0/0
          AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
          ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
      
      Resources:
        WebServerSecurityGroup:
          Type: AWS::EC2::SecurityGroup
          Properties:
            GroupDescription: Allow HTTP access via my IP address
            SecurityGroupIngress:
              - IpProtocol: tcp
                FromPort: 80
                ToPort: 80
                CidrIp: !Ref MyIP
      
        WebServer:
          Type: AWS::EC2::Instance
          Properties:
            ImageId: !Ref LatestAmiId
            InstanceType: !Ref InstanceType
            SecurityGroupIds:
              - !Ref WebServerSecurityGroup
            UserData: !Base64 |
              #!/bin/bash
              yum update -y
              yum install -y httpd
              systemctl start httpd
              systemctl enable httpd
              echo "<html><body><h1>Hello World!</h1></body></html>" > /var/www/html/index.html
      
      Outputs:
        WebsiteURL:
          Value: !Join
            - ''
            - - http://
              - !GetAtt WebServer.PublicDnsName
          Description: Website URL
      ```

      在继续下一步之前，我们花些时间来了解一下模板和一些关键的 CloudFormation 概念。
      + **`Parameters`** 部分声明在创建堆栈时可传递给模板的值。稍后在模板中指定的资源会引用这些值并使用这些数据。如果要指定不想存储在模板内的信息，使用参数就是非常有效的办法。这种方法也可以用于指定对正在部署的特定应用程序或配置可能具有唯一性的信息。
      + 模板会定义以下参数：
        + **`LatestAmiId`** – 从 AWS Systems Manager Parameter Store 检索最新的 Amazon Linux 2 AMI ID。
        + **`InstanceType`** – 允许选择 EC2 实例类型（默认：`t2.micro`，允许：`t3.micro`、`t2.micro`）。
        + **`MyIP`** – 指定 HTTP 访问权限的 IP 地址范围（默认：0.0.0.0/0，允许来自任意 IP 的访问）。
      + **`Resources`** 部分包含要使用该模板创建的 AWS 资源的定义。资源声明是立即指定这些所有配置设置的一种有效方法。如果您将资源声明放入模板，您将可以使用该模板创建和配置所有的声明资源，从而创建堆栈。您也可以使用相同模板创建新的堆栈，来启动相同的资源配置。
      + 此模板创建以下资源：
        + **`WebServerSecurityGroup`** – EC2 安全组，允许来自指定 IP 范围的端口 80 上的入站 HTTP 流量。
        + **`WebServer`** – 具有以下配置的 EC2 实例：
          + 使用最新的 Amazon Linux 2 AMI
          + 应用选定的实例类型
          + 将 `WebServerSecurityGroup` 添加到 `SecurityGroupIds`属性
          + 包括用于安装 Apache HTTP 服务器的用户数据脚本
      + 在每个资源和参数声明的开头都指定逻辑名称。例如，`WebServerSecurityGroup` 是分配给 EC2 安全组资源的逻辑名称。然后，系统会使用 `Ref` 函数来按资源和参数在模板其他部分中的逻辑名称来引用资源和参数。如果一个资源引用另一个资源，两者之间会形成依赖关系。
      + **`Outputs`** 部分定义堆栈创建后返回的自定义值。您可以使用输出值在堆栈中返回来自资源的信息，例如资源标识符或 URL。
      + 该模板定义了一个输出：
        + **`WebsiteURL`** – 已部署 Web 服务器的 URL（使用 EC2 实例的公有 DNS 名称构建）。`Join` 函数可以将固定 `http://` 和可变 `PublicDnsName` 组合成一个字符串，从而轻松输出 Web 服务器的完整 URL。

   1. 选择**验证**以确保 YAML 代码有效，然后再上传模板。

   1. 接下来，选择**创建模板**以创建模板并将其添加到 S3 存储桶。

   1. 在开启的对话框中，记下 S3 存储桶的名称，之后便可删除。然后，选择**确认并继续前往 CloudFormation**。这会将您转至 CloudFormation 控制台，现在模板的 S3 路径已在控制台中指定。

1. 在**创建堆栈**主页上，选择**下一步**。

1. 在**指定堆栈详细信息**页面的**堆栈名称**字段中，输入名称。堆栈名中不得含有空格。对于本示例，请使用 **MyTestStack**。

1. 在**参数**下，指定参数值，如下所示：
   + **LatestAmiId**：此值默认设定为最新的 Amazon Linux 2 AMI。
   + **InstanceType**：选择 **t2.micro** 或 **t3.micro** 作为 EC2 实例类型。
**注意**  
如果您是 AWS 新用户，您可以使用免费套餐在 12 个月内免费启动和使用 `t2.micro` 实例（在 `t2.micro` 不可用的区域，您可以通过免费套餐使用 `t3.micro` 实例）。
   + **MyIP**：使用 `/32` 后缀指定实际公有 IP 地址。在 CIDR 表示法中使用 `/32` 后缀来指定允许使用单个 IP 地址。这基本上意味着仅允许流入和流出此特定 IP 地址的流量，而不允许其他 IP 地址的流量。

1. 选择**下一步**两次，前往**检查和创建**页面。在本教程中，您可以保留**配置堆栈选项**页面的默认值。

1. 审查堆栈信息。如果对设置满意，请选择 **Submit (提交)**。

## 监控堆栈创建
<a name="getting-started-monitor-stack-creation"></a>

选择**提交**后，CloudFormation 将开始创建模板中指定的资源。您的新堆栈 (**MyTestStack**) 将显示在 **CloudFormation** 控制台顶部的列表中。状态应为 `CREATE_IN_PROGRESS`。您可以通过查看事件了解堆栈的详细状态。

**想要查看堆栈的事件**

1. 在 CloudFormation 控制台上，选择列表中的堆栈 **MyTestStack**。

1. 在堆栈详细信息窗格中，选择 **Events (事件)** 选项卡。

   控制台每 60 秒自动使用最新事件刷新事件列表。

**Events (事件)** 选项卡显示堆栈创建过程中的每个重要步骤（按每个事件的时间排序，最新事件位于最上面）。

第一个事件 (在事件列表最底部) 为堆栈创建过程的开始：

`2024-12-23 18:54 UTC-7 MyTestStack CREATE_IN_PROGRESS User initiated`

下面是标志所有资源创建开始和完成的事件。例如，创建 EC2 实例后会产生以下条目：

`2024-12-23 18:59 UTC-7 WebServer CREATE_COMPLETE`

`2024-12-23 18:54 UTC-7 WebServer CREATE_IN_PROGRESS Resource creation initiated`

当 CloudFormation 报告它已开始创建资源时，将记录 `CREATE_IN_PROGRESS` 事件。在资源创建成功时，将记录 `CREATE_COMPLETE` 事件。

当 CloudFormation 成功创建了堆栈时，您将会在 **Event (事件)** 选项卡顶部看到下列事件：

`2024-12-23 19:17 UTC-7 MyTestStack CREATE_COMPLETE`

如果 CloudFormation 无法创建资源，它将报告 `CREATE_FAILED` 事件，并（在默认情况下）回滚堆栈、删除已创建的所有资源。**状态原因**列显示已导致失败的问题。

创建堆栈后，您可以前往**资源**选项卡查看创建的 EC2 实例和安全组。

## 测试 Web 服务器
<a name="getting-started-test-web-server"></a>

成功创建堆栈后，在 CloudFormation 控制台中前往**输出**选项卡。找到 **WebsiteURL** 字段。字段中会包含 EC2 实例的公有 URL。

打开浏览器并前往 **WebsiteURL** 下列出的 URL。您会在浏览器中看到一条简单的 "Hello World\$1" 消息。

这表示您的 EC2 实例正在运行 Apache HTTP 服务器并提供基本网页。

## 问题排查
<a name="getting-started-troubleshooting"></a>

如果您在创建堆栈期间遇到回滚，这可能是缺少 VPC 所致。解决办法如下。

### 没有可用的默认 VPC
<a name="getting-started-troubleshooting-no-default-vpc"></a>

本演练中的模板需要默认 VPC。如果因为 VPC 或子网可用性错误而出现堆栈创建失败的情况，这可能是因为账户中没有默认 VPC。您有以下选项：
+ **创建新的默认 VPC**：可以通过 Amazon VPC 控制台创建新的默认 VPC。有关说明，请参阅《Amazon VPC 用户指南》**中的[创建默认 VPC](https://docs.aws.amazon.com/vpc/latest/userguide/work-with-default-vpc.html#create-default-vpc)。
+ **修改模板以指定子网**：如果您有非默认 VPC，则可以修改模板以明确指定 VPC 和子网 ID。将以下参数添加到模板：

  ```
    SubnetId:
      Description: The subnet ID to launch the instance into
      Type: AWS::EC2::Subnet::Id
  ```

  然后，更新 `WebServer` 资源以包含子网 ID：

  ```
    WebServer:
      Type: AWS::EC2::Instance
      Properties:
        ImageId: !Ref LatestAmiId
        InstanceType: !Ref InstanceType
        SecurityGroupIds:
          - !Ref WebServerSecurityGroup
        SubnetId: !Ref SubnetId
        UserData: !Base64 |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<html><body><h1>Hello World!</h1></body></html>" > /var/www/html/index.html
  ```

  创建堆栈时，您需要指定一个可以访问互联网的子网才能确保 Web 服务器可供访问。

## 清理
<a name="getting-started-clean-up"></a>

为了保证您不为不需要的服务承担费用，您可以通过删除堆栈和它的资源进行清理。您也可以删除存储堆栈模板的 S3 存储桶。

**想要删除堆栈和它的资源**

1. 打开 [ CloudFormation 控制台](https://console.aws.amazon.com/cloudformation/)。

1. 在**堆栈**页面上，选择您创建的堆栈名称旁的选项（**MyTestStack**），然后选择**删除**。

1. 当系统提示进行确认时，选择 **Delete（删除）**。

1. 在**事件**选项卡上监控堆栈删除过程的进度。**MyTestStack** 的状态更改为 `DELETE_IN_PROGRESS`。当 CloudFormation 完成删除堆栈后，它会将从列表中移堆栈除。

如果您已完成此示例模板的使用，不再需要 Amazon S3 存储桶，请将其删除。您必须先清空存储桶，然后才能删除存储桶。清空存储桶将删除存储桶中的所有对象。

**清空和删除 Amazon S3 存储桶**

1. 打开 [Amazon S3 控制台](https://console.aws.amazon.com/s3/)。

1. 在控制台左侧的导航窗格中，选择 **Buckets（存储桶）**。

1. 在**存储桶**列表中，选择要为本教程创建的存储桶名称旁的选项，然后选择**清空**。

1. 在**清空存储桶**页面上，通过在文本字段中键入 **permanently delete** 来确认要清空存储桶，然后选择**清空**。

1. 在**清空存储桶：状态**页面上监控存储桶清空过程的进度。

1. 要返回到存储桶列表，请选择**退出**。

1. 选择存储桶名称旁的选项，然后选择**删除**。

1. 在系统提示进行确认时，键入存储桶的名称，然后选择**删除存储桶**。

1. 在**存储桶**清单上监控存储桶删除过程的进度。Amazon S3 完成存储桶删除后，会将存储桶从列表中移除。

## 后续步骤
<a name="getting-started-next-steps"></a>

恭喜您！您已成功创建了堆栈、监控了堆栈的创建并使用了堆栈的输出。

继续学习：
+ 详细了解模板以便自己创建模板。有关更多信息，请参阅 [使用 CloudFormation 模板](template-guide.md)。
+ 试试参加 [CloudFormation 入门](https://catalog.us-east-1.prod.workshops.aws/workshops/df7f72cf-4f10-4664-acb6-b30dc8d4bcf0/en-US)研习会，获得更多模板创建动手实践。
+ 有关 [CloudFormation 入门](https://catalog.us-east-1.prod.workshops.aws/workshops/df7f72cf-4f10-4664-acb6-b30dc8d4bcf0/en-US)的简短版本，请参阅[在 Amazon EC2 上部署应用程序](deploying.applications.md)。本主题同样描述了使用 CloudFormation 帮助程序脚本 `cfn-init` 的情境，但是用于引导 Amazon EC2 实例。