

# CloudFormation 模板部分
<a name="template-anatomy"></a>

每个 CloudFormation 模板都由一个或多个部分组成，每个部分都有特定的用途。

每个 CloudFormation 模板都需要有 **Resources** 部分，这是模板的核心。这一部分用于指定堆栈资源及其属性，如 Amazon EC2 实例或 Amazon S3 存储桶。每个资源都使用唯一的逻辑 ID、类型和特定的配置详细信息进行定义。

**Parameters** 部分尽管是可选的，但对于提高模板的灵活性十分重要。这一部分让用户能够在创建或更新堆栈时传递运行时的值。这些参数可以在 `Resources` 和 `Outputs` 部分中引用，从而无需更改模板本身即可进行自定义。例如，您可以使用参数来指定不同部署的实例类型或环境设置。

**Outputs** 部分也是可选的，用于定义查看堆栈属性时返回的值。输出提供了可用于操作目的或与其他堆栈集成的实用信息，例如资源标识符或 URL 等。这一部分有助于用户检索和使用与模板所创建资源有关的重要详细信息。

其他可选部分包括 **Mappings**，其功能类似于查找表，用于管理条件值。使用映射，您可以定义键值对，并将其与 `Resources` 和 `Outputs` 部分中的 `Fn::FindInMap` 内置函数结合使用。这对于需要根据条件（例如 AWS 区域 或环境）调整配置的场景非常实用。

**Metadata** 和 **Rules** 部分虽然不太常用，但提供了额外的功能。`Metadata` 可以包含有关模板的更多信息，而 `Rules` 会在堆栈创建或更新期间验证参数或参数组合，确保符合特定标准。**Conditions** 部分根据环境类型等条件来控制是否创建特定的资源或者属性分配值，从而进一步提高灵活性。

最后是 **Transform** 部分，用于在处理模板期间应用宏。对于无服务器应用程序（也称为 Lambda 应用程序），这一部分会指定要使用的 [AWS Serverless Application Model（AWS SAM）](https://github.com/awslabs/serverless-application-specification)版本。当您指定转换时，可以使用 AWS SAM 语法声明您的模板中的资源。此模型定义您可使用的语法及其处理方式。您也可以使用 `AWS::Include` 转换来包含与主 CloudFormation 模板分开存储的模板代码片段。

以下主题提供了有关如何使用每个部分的更多信息和示例。

**Topics**
+ [Resources](resources-section-structure.md)
+ [Parameters](parameters-section-structure.md)
+ [Outputs](outputs-section-structure.md)
+ [Mappings](mappings-section-structure.md)
+ [Metadata](metadata-section-structure.md)
+ [Rules](rules-section-structure.md)
+ [Conditions](conditions-section-structure.md)
+ [Transform](transform-section-structure.md)
+ [格式版本](format-version-structure.md)
+ [Description](template-description-structure.md)

# CloudFormation 模板 Resources 语法
<a name="resources-section-structure"></a>

`Resources` 部分是 CloudFormation 模板中必需具备的一个顶级部分，用于声明您希望 CloudFormation 在堆栈中预置和配置的 AWS 资源。

## 语法
<a name="resources-section-structure-syntax"></a>

`Resources` 部分使用以下语法：

### JSON
<a name="resources-section-structure-syntax.json"></a>

```
"Resources" : {
    "LogicalResourceName1" : {
        "Type" : "AWS::ServiceName::ResourceType",
        "Properties" : {
            "PropertyName1" : "PropertyValue1",
            ...
        }
    },

    "LogicalResourceName2" : {
        "Type" : "AWS::ServiceName::ResourceType",
        "Properties" : {
            "PropertyName1" : "PropertyValue1",
            ...
        }
    }
}
```

### YAML
<a name="resources-section-structure-syntax.yaml"></a>

```
Resources:
  LogicalResourceName1:
    Type: AWS::ServiceName::ResourceType
    Properties:
      PropertyName1: PropertyValue1
      ...

  LogicalResourceName2:
    Type: AWS::ServiceName::ResourceType
    Properties:
      PropertyName1: PropertyValue1
      ...
```

## 逻辑 ID（也称为*逻辑名称*）
<a name="resources-section-logical-id"></a>

在 CloudFormation 模板中，资源由其逻辑资源名称来标识。这些名称必须为字母数字字符（A-Za-z0-9），并且在模板中必须唯一。逻辑名称用于引用模板其他部分中的资源。

## 资源类型
<a name="resources-section-resource-type"></a>

每个资源必须有一个 `Type` 属性，用于定义 AWS 资源的类型。`Type` 属性的格式为 `AWS::ServiceName::ResourceType`。例如，Amazon S3 存储桶的 `Type` 属性为 `AWS::S3::Bucket`。

有关支持的资源类型的完整列表，请参阅 [AWS 资源和属性类型参考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)。

## 资源属性
<a name="resources-section-resource-properties"></a>

资源属性是可以指定的附加选项，用于定义特定资源类型的详细配置。某些属性是必需的，而另一些属性则是可选的。有些属性具有默认值，因此指定这些属性是可选的。

有关每种资源类型支持的属性的详细信息，请参阅 [AWS 资源和属性类型参考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)中的主题。

属性值可以是文本字符串、字符串列表、布尔值、动态引用、参数引用、伪引用或者函数返回的值。以下示例演示了如何声明不同的属性值类型：

### JSON
<a name="resource-properties-example.json"></a>

```
"Properties" : {
    "String" : "A string value",
    "Number" : 123,
    "LiteralList" : [ "first-value", "second-value" ],
    "Boolean" : true
}
```

### YAML
<a name="resource-properties-example.yaml"></a>

```
Properties:
  String: A string value 
  Number: 123
  LiteralList:
    - first-value
    - second-value
  Boolean: true
```

## 物理 ID
<a name="resources-section-physical-id"></a>

除了逻辑 ID 外，某些资源还有物理 ID，这是资源的实际分配名称，如 EC2 实例 ID 或 S3 存储桶名称。使用物理 ID 来标识 CloudFormation 模板外部的资源，但只能在创建了资源之后进行。例如，假设您为一个 EC2 实例资源指定 `MyEC2Instance` 的逻辑 ID。当 CloudFormation 创建实例时，CloudFormation 会自动生成物理 ID（如 `i-1234567890abcdef0`）并将其分配给该实例。您可以使用该物理 ID 来标识实例，可以使用 Amazon EC2 控制台查看其属性 (如 DNS 名称)。

对于 Amazon S3 存储桶和许多其他资源，如果您没有明确指定实体名称，CloudFormation 会自动为该资源生成唯一的实体名称。该实体名称基于 CloudFormation 堆栈的名称、在 CloudFormation 模板中指定的资源逻辑名称和唯一 ID 的组合。例如，假设您在名为 `MyStack` 的堆栈中有一个逻辑名称为 `MyBucket` 的 Amazon S3 存储桶，CloudFormation 可能会使用如下物理名称 `MyStack-MyBucket-abcdefghijk1` 来命名该存储桶。

对于支持自定义名称的资源，您可以分配自己的物理名称来帮助快速标识资源。例如，您可以将存储日志的 S3 存储桶命名为 `MyPerformanceLogs`。有关更多信息，请参阅[名称类型](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-name.html)。

## 引用资源
<a name="using-cross-resource-references"></a>

您经常会需要根据一个资源的名称或属性来设置另一个资源的属性。例如，您可以创建一个使用 EC2 安全组的 EC2 实例，或由 S3 存储桶支持的 CloudFront 分配。所有这些资源都可在同一 CloudFormation 模板中创建。

CloudFormation 提供了内置函数，您可以使用这些函数来引用其他资源及其属性。这些函数让您可以在资源之间创建依赖关系，并将一个资源的值传递到另一个资源。

### `Ref` 函数
<a name="resource-properties-ref"></a>

`Ref` 函数通常用于检索在同一 CloudFormation 模板中定义的资源的标识属性。具体返回的值取决于资源的类型。对于大多数资源，该函数会返回资源的实体名称。不过对于某些资源类型，该函数可能会返回其他的值，例如 `AWS::EC2::EIP` 资源的 IP 地址或 Amazon SNS 主题的 Amazon 资源名称（ARN）。

以下示例演示了如何在属性中使用 `Ref` 函数。在以下的每个示例中，`Ref` 函数都将返回模板中其他部分声明的 `LogicalResourceName` 资源的实际名称。YAML 示例中的 `!Ref` 语法示例只是编写 `Ref` 函数的较简单方法。

#### JSON
<a name="resource-properties-ref-example.json"></a>

```
"Properties" : {
    "PropertyName" : { "Ref" : "LogicalResourceName" }
}
```

#### YAML
<a name="resource-properties-ref-example.yaml"></a>

```
Properties:
  PropertyName1:
    Ref: LogicalResourceName
  PropertyName2: !Ref LogicalResourceName
```

有关使用 `Ref` 函数的更多详细信息，请参阅 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-ref.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-ref.html)。

### `Fn::GetAtt` 函数
<a name="resource-properties-getatt"></a>

如果参数或为资源返回的值正是您需要的，则 `Ref` 函数会非常实用。不过，您可能需要资源的其他属性。例如，如果您想创建一个具有 S3 起始地址的 CloudFront 分配，就需要使用 DNS 样式的地址来指定存储桶的位置。很多资源都具有附加属性，您可以在模板中使用这些属性的值。要获取这些属性，请使用 `Fn::GetAtt` 函数。

以下示例演示了如何在属性中使用 `GetAtt` 函数。`Fn::GetAtt` 函数有两个参数，分别是资源的逻辑名称和要检索的属性名称。YAML 示例中的 `!GetAtt` 语法示例只是编写 `GetAtt` 函数的较简单方法。

#### JSON
<a name="resource-properties-getatt-example.json"></a>

```
"Properties" : {
    "PropertyName" : {
        "Fn::GetAtt" : [ "LogicalResourceName", "AttributeName" ]
    }
}
```

#### YAML
<a name="resource-properties-getatt-example.yaml"></a>

```
Properties:
  PropertyName1:
    Fn::GetAtt:
      - LogicalResourceName
      - AttributeName
  PropertyName2: !GetAtt LogicalResourceName.AttributeName
```

有关使用 `GetAtt` 函数的更多详细信息，请参阅 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-getatt.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-getatt.html)。

## 示例
<a name="resources-section-structure-examples"></a>

以下示例演示了如何声明资源以及 CloudFormation 模板会如何引用在同一模板中定义的其他资源以及现有的 AWS 资源。

**Topics**
+ [使用自定义名称声明单个资源](#resources-section-structure-examples-single-resource)
+ [使用 `Ref` 函数引用其他资源](#resources-section-structure-examples-ref)
+ [使用 `Fn::GetAtt` 函数引用资源属性](#resources-section-structure-examples-getatt)

### 使用自定义名称声明单个资源
<a name="resources-section-structure-examples-single-resource"></a>

以下示例声明了 `AWS::S3::Bucket` 类型的单个资源，逻辑名称为 `MyBucket`。`BucketName` 属性设置为 *amzn-s3-demo-bucket*，因此应替换为您的 S3 存储桶所需的名称。

如果您使用此资源声明创建堆栈，CloudFormation 将使用默认设置创建 Amazon S3 存储桶。对于 Amazon EC2 实例或自动扩缩组等其他资源，CloudFormation 需要更多信息。

#### JSON
<a name="resources-section-structure-examples-single-resource.json"></a>

```
{
    "Resources": {
        "MyBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": "amzn-s3-demo-bucket"
            }
        }
    }
}
```

#### YAML
<a name="resources-section-structure-examples-single-resource.yaml"></a>

```
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: amzn-s3-demo-bucket
```

### 使用 `Ref` 函数引用其他资源
<a name="resources-section-structure-examples-ref"></a>

以下示例演示的资源声明定义了一个 EC2 实例和安全组。`Ec2Instance` 资源使用 `Ref` 函数引用 `InstanceSecurityGroup` 资源，以作为其 `SecurityGroupIds` 属性的一部分。此外还包括未在模板中声明的一个现有安全组 (`sg-12a4c434`)。您可以使用文字字符串来指代现有 AWS 资源。

#### JSON
<a name="resources-section-structure-examples-ref.json"></a>

```
{
    "Resources": {
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "SecurityGroupIds": [
                    {
                        "Ref": "InstanceSecurityGroup"
                    },
                    "sg-12a4c434"
                ],
                "KeyName": "MyKey",
                "ImageId": "ami-1234567890abcdef0"
            }
        },
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        }
    }
}
```

#### YAML
<a name="resources-section-structure-examples-ref.yaml"></a>

```
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
        - sg-12a4c434
      KeyName: MyKey
      ImageId: ami-1234567890abcdef0
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
```

### 使用 `Fn::GetAtt` 函数引用资源属性
<a name="resources-section-structure-examples-getatt"></a>

以下示例演示的资源声明定义了一个 CloudFront 分配资源和一个 S3 存储桶。`MyDistribution` 资源指定了 `MyBucket` 资源的 DNS 名称，后者使用 `Fn::GetAtt` 函数来获取存储桶的 `DomainName` 属性。`Fn::GetAtt` 函数会在一个数组中列出这两个参数。对于采用多个参数的函数，可以使用数组来指定其参数。

#### JSON
<a name="resources-section-structure-examples-getatt.json"></a>

```
{
  "Resources": {
    "MyBucket": {
      "Type": "AWS::S3::Bucket"
    },
    "MyDistribution": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Origins": [
            {
              "DomainName": {
                "Fn::GetAtt": [
                  "MyBucket",
                  "DomainName"
                ]
              },
              "Id": "MyS3Origin",
              "S3OriginConfig": {}
            }
          ],
          "Enabled": "true",
          "DefaultCacheBehavior": {
            "TargetOriginId": "MyS3Origin",
            "ForwardedValues": {
              "QueryString": "false"
            },
            "ViewerProtocolPolicy": "allow-all"
          }
        }
      }
    }
  }
}
```

#### YAML
<a name="resources-section-structure-examples-getatt.yaml"></a>

```
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
  MyDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
          - DomainName: !GetAtt 
              - MyBucket
              - DomainName
            Id: MyS3Origin
            S3OriginConfig: {}
        Enabled: 'true'
        DefaultCacheBehavior:
          TargetOriginId: MyS3Origin
          ForwardedValues:
            QueryString: 'false'
          ViewerProtocolPolicy: allow-all
```

# CloudFormation 模板 Parameters 语法
<a name="parameters-section-structure"></a>

使用可选的 `Parameters` 部分来自定义模板。利用参数，您能够在每次创建或更新堆栈时在模板中输入自定义值。通过在模板中使用参数，您可以构建可重复使用的灵活模板，以便根据具体场景进行自定义。

通过定义适当类型的参数，您可以在使用控制台创建堆栈时从现有资源的标识符列表中进行选择。有关更多信息，请参阅 [使用 CloudFormation 提供的参数类型在运行时指定现有资源](cloudformation-supplied-parameter-types.md)。

参数是指定堆栈资源属性值的一种常用方法。但是，可能会有一些因区域而异的设置，或是一些因其他条件或依赖关系而需要用户确定的复杂设置。在这些情况下，您可能需要将一些逻辑放入模板本身中，以便用户可以指定简单值（或不指定任何值）来获得期望的结果，例如通过使用映射。有关更多信息，请参阅 [CloudFormation 模板 Mappings 语法](mappings-section-structure.md)。

## 语法
<a name="parameters-section-structure-syntax"></a>

您需要在模板的 `Parameters` 部分声明参数，该部分会使用以下通用语法：

### JSON
<a name="parameters-section-structure-syntax.json"></a>

```
"Parameters" : {
  "ParameterLogicalID" : {
    "Description": "Information about the parameter",
    "Type" : "DataType",
    "Default" : "value",
    "AllowedValues" : ["value1", "value2"]
  }
}
```

### YAML
<a name="parameters-section-structure-syntax.yaml"></a>

```
Parameters:
  ParameterLogicalID:
    Description: Information about the parameter
    Type: DataType
    Default: value
    AllowedValues:
      - value1
      - value2
```

一个参数包含一系列属性，这些属性定义了其值但也限制了其值。唯一必需的属性是 `Type`，该属性可以是 `String`、`Number` 或 CloudFormation 提供的参数类型。您还可以添加 `Description` 属性来描述要指定的值的类型。在**创建堆栈**向导中使用该模板时，参数的名称和描述会在**指定参数**页面中显示。

**注意**  
默认情况下，CloudFormation 控制台按照输入参数的逻辑 ID 的字母顺序列出这些参数。要覆盖此默认排序并将相关参数组合在一起，您可以在模板中使用 `AWS::CloudFormation::Interface` 元数据键。有关更多信息，请参阅 [使用 `AWS::CloudFormation::Interface` 元数据整理 CloudFormation 参数](aws-cloudformation-interface.md)。

对于具有默认值的参数，CloudFormation 将使用默认值，除非用户指定其他值。如果省略默认属性，则用户将需要指定该参数的值。但是，要求用户输入值并不能确保该值有效。要验证参数的值，您可以声明一些约束或指定某个特定于 AWS 的参数类型。

对于没有默认值的参数，用户必须在创建堆栈时指定一个键名称值。否则，CloudFormation 将无法创建堆栈并引发异常：

```
Parameters: [KeyName] must have values
```

## 属性
<a name="parameters-section-structure-properties"></a>

`AllowedPattern`  
一个正则表达式，表示要允许 `String` 和 `CommaDelimitedList` 类型使用的模式。应用于类型为 `String` 的参数时，模式必须与提供的整个参数值匹配。应用于类型为 `CommaDelimitedList` 的参数时，模式必须与列表中的每个值匹配。  
*必需*：否

`AllowedValues`  
包含参数允许值列表的阵列。应用于类型为 `String` 的参数时，该参数值必须是允许的值之一。应用于类型为 `CommaDelimitedList` 的参数时，列表中的每个值都必须是指定的允许的值之一。  
*必需*：否  
如果您使用 YAML，并且想要在 `AllowedValues` 中使用 `Yes` 和 `No` 字符串，请使用单引号来防止 YAML 解析器考虑这些布尔值。

`ConstraintDescription`  
用于在违反约束时说明该约束的字符串。例如，在没有约束条件描述的情况下，具有允许的 `[A-Za-z0-9]+` 模式的参数会在用户指定无效值时显示以下错误消息：  
`Malformed input-Parameter MyParameter must match pattern [A-Za-z0-9]+`  
通过添加约束描述（如 *must only contain letters (uppercase and lowercase) and numbers*），您可以显示以下自定义的错误消息：  
`Malformed input-Parameter MyParameter must only contain uppercase and lowercase letters and numbers`  
*必需*：否

`Default`  
模板适当类型的值，用于在创建堆栈时未指定值的情况下。如果您定义参数的约束，则必须指定一个符合这些约束的值。  
*必需*：否

`Description`  
用于描述参数的长度最多为 4000 个字符的字符串。  
*必需*：否

`MaxLength`  
一个整数值，确定要允许 `String` 类型使用的字符的最大数目。  
*必需*：否

`MaxValue`  
一个数字值，确定要允许 `Number` 类型使用的最大数字值。  
*必需*：否

`MinLength`  
一个整数值，确定要允许 `String` 类型使用的字符的最小数目。  
*必需*：否

`MinValue`  
一个数字值，确定要允许 `Number` 类型使用的最小数字值。  
*必需*：否

`NoEcho`  
是否遮蔽参数值以防止在控制台、命令行或 API 中显示。如果您将 `NoEcho` 属性设置为 `true`，则对于描述堆栈或堆栈事件的任何调用，CloudFormation 返回使用星号 (\$1\$1\$1\$1\$1) 遮蔽的参数值，但存储在下面指定位置的信息除外。  
*必需*：否  
使用 `NoEcho` 属性不会遮蔽在以下各区段中存储的任何信息：  
+ `Metadata` 模板区段。CloudFormation 不会转换、修改或编辑您在 `Metadata` 部分中包含的任何信息。有关更多信息，请参阅 [Metadata](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html)。
+ `Outputs` 模板区段。有关更多信息，请参阅 [Outputs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)。
+ 资源定义的 `Metadata` 属性。有关更多信息，请参阅 [`Metadata` 属性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html)。
强烈建议您不要使用这些机制来包含敏感信息，例如密码。
我们建议不要将敏感信息直接嵌入 CloudFormation 模板中，而应使用堆栈模板中的动态参数来引用在 CloudFormation 外部存储和管理的敏感信息，例如 AWS Systems Manager Parameter Store 或 AWS Secrets Manager 中的敏感信息。  
有关更多信息，请参阅[请勿将凭证嵌入您的模板](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/security-best-practices.html#creds)最佳实践。
我们建议不要在作为资源主标识符一部分的资源属性中包含 `NoEcho` 参数或任何敏感数据。  
当 `NoEcho` 参数包含在构成主资源标识符的属性中时，CloudFormation 可能会在主资源标识符中使用*实际明文值*。此资源 ID 可能出现在任何派生输出或目标中。  
要确定哪些资源属性构成了资源类型的主标识符，请参阅 [AWS 资源和属性类型参考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)中该资源的资源参考文档。在 **Return values**（返回值）部分，`Ref` 函数返回值，表示构成资源类型主标识符的资源属性。

`Type`  <a name="parameters-section-structure-properties-type"></a>
参数 (`DataType`) 的数据类型。  
*是否必需*：是  
CloudFormation 支持以下参数类型：    
`String`  
一个文字字符串。您可以使用以下属性来声明约束：`MinLength`、`MaxLength`、`Default`、`AllowedValues` 和 `AllowedPattern`。  
例如，用户可指定 `"MyUserName"`。  
`Number`  
整型或浮点型。CloudFormation 将参数值作为数字进行验证；但当您在模板中的其他位置使用参数时（例如，通过使用 `Ref` 内置函数），该参数值将变为字符串。  
您可以使用以下属性来声明约束：`MinValue`、`MaxValue`、`Default` 和 `AllowedValues`。  
例如，用户可指定 `"8888"`。  
`List<Number>`  
以逗号分隔的整型或浮点型数组。CloudFormation 将参数值作为数字进行验证；但当您在模板中的其他位置使用参数时（例如，通过使用 `Ref` 内置函数），该参数值将变为字符串列表。  
例如，用户可指定 `"80,20"`，并且 `Ref` 将生成 `["80","20"]`。  
`CommaDelimitedList`  
一组用逗号分隔的文本字符串。字符串的总数应比逗号总数多 1。此外，会对每个成员字符串进行空间修剪。  
例如，用户可指定 `"test,dev,prod"`，并且 `Ref` 将生成 `["test","dev","prod"]`。  
特定于 AWS 的参数类型  
AWS 值，例如 Amazon EC2 密钥对名称和 VPC ID。有关更多信息，请参阅 [在运行时指定现有资源](cloudformation-supplied-parameter-types.md)。  
Systems Manager 参数类型  
与 Systems Manager Parameter Store 中的现有参数对应的参数。您指定 Systems Manager 参数键作为 Systems Manager 参数类型的值，然后 CloudFormation 从 Parameter Store 中检索最新的值来用于堆栈。有关更多信息，请参阅 [在运行时指定现有资源](cloudformation-supplied-parameter-types.md)。

## 参数的一般要求
<a name="parameters-section-structure-requirements"></a>

使用参数时存在以下要求：
+ 一个 CloudFormation 模板中最多可包含 200 个参数。
+ 必须为每个参数提供一个逻辑名称（也称为逻辑 ID），该名称必须是字母数字，并且在模板内的所有逻辑名称中必须唯一。
+ 必须向每个参数分配一个 CloudFormation 支持的参数类型。有关更多信息，请参阅[类型](#parameters-section-structure-properties-type)。
+ 必须向每个参数分配一个运行时的值，这样 CloudFormation 才能成功预置堆栈。您可以选择为要使用的 CloudFormation 指定默认值，除非提供有其他值。
+ 必须在同一模板内声明和引用参数。您可以引用模板的 `Resources` 和 `Outputs` 部分中的参数。

## 示例
<a name="parameters-section-examples"></a>

**Topics**
+ [简单字符串参数](#parameters-section-structure-example-1)
+ [密码参数](#parameters-section-structure-example-2)
+ [引用参数](#parameters-section-structure-example-3)
+ [逗号分隔列表参数](#parameters-section-structure-example-4)
+ [从逗号分隔列表参数返回值](#parameters-section-structure-example-5)

### 简单字符串参数
<a name="parameters-section-structure-example-1"></a>

以下示例声明了一个名为 `InstanceTypeParameter`，类型为 `String` 的参数。利用此参数，您可以为堆栈指定 Amazon EC2 实例类型。如果在创建或更新堆栈期间未提供任何值，CloudFormation 将使用 `t2.micro` 的默认值。

#### JSON
<a name="parameters-section-structure-example-1.json"></a>

```
"Parameters" : {
  "InstanceTypeParameter" : {
    "Description" : "Enter t2.micro, m1.small, or m1.large. Default is t2.micro.",
    "Type" : "String",
    "Default" : "t2.micro",
    "AllowedValues" : ["t2.micro", "m1.small", "m1.large"]
  }
}
```

#### YAML
<a name="parameters-section-structure-example-1.yaml"></a>

```
Parameters:
  InstanceTypeParameter:
    Description: Enter t2.micro, m1.small, or m1.large. Default is t2.micro.
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - m1.small
      - m1.large
```

### 密码参数
<a name="parameters-section-structure-example-2"></a>

以下示例声明了一个名为 `DBPwd`，类型为 `String` 且没有默认值的参数。将 `NoEcho` 属性设置为 `true` 是为了防止在堆栈描述中显示参数值。可指定的最小长度为 `1`，可指定的最大长度为 `41`。该模式允许小写和大写字母字符和数字。此示例还演示了 `AllowedPattern` 属性的正则表达式用法。

#### JSON
<a name="parameters-section-structure-example-2.json"></a>

```
"Parameters" : {
  "DBPwd" : {
    "NoEcho" : "true",
    "Description" : "The database admin account password",
    "Type" : "String",
    "MinLength" : "1",
    "MaxLength" : "41",
    "AllowedPattern" : "^[a-zA-Z0-9]*$"
  }
}
```

#### YAML
<a name="parameters-section-structure-example-2.yaml"></a>

```
Parameters: 
  DBPwd: 
    NoEcho: true
    Description: The database admin account password
    Type: String
    MinLength: 1
    MaxLength: 41
    AllowedPattern: ^[a-zA-Z0-9]*$
```

### 引用参数
<a name="parameters-section-structure-example-3"></a>

您可以使用 `Ref` 内置函数来引用某个参数，然后 CloudFormation 将使用该参数的值来预置堆栈。您可以引用同一模板的 `Resources` 和 `Outputs` 部分中的参数。

在以下示例中，EC2 实例资源的 `InstanceType` 属性引用了 `InstanceTypeParameter` 参数值：

#### JSON
<a name="parameters-section-structure-example-3.json"></a>

```
"Ec2Instance" : {
  "Type" : "AWS::EC2::Instance",
  "Properties" : {
    "InstanceType" : { "Ref" : "InstanceTypeParameter" },
    "ImageId" : "ami-0ff8a91507f77f867"
  }
}
```

#### YAML
<a name="parameters-section-structure-example-3.yaml"></a>

```
Ec2Instance:
  Type: AWS::EC2::Instance
  Properties:
    InstanceType:
      Ref: InstanceTypeParameter
    ImageId: ami-0ff8a91507f77f867
```

### 逗号分隔列表参数
<a name="parameters-section-structure-example-4"></a>

需要为单个属性提供多个值时，`CommaDelimitedList` 参数类型可能非常实用。以下示例声明了一个名为 `DbSubnetIpBlocks` 的参数，其默认值为用逗号分隔的三个 CIDR 块。

#### JSON
<a name="parameters-section-structure-example-4.json"></a>

```
"Parameters" : {
  "DbSubnetIpBlocks": {
    "Description": "Comma-delimited list of three CIDR blocks",
    "Type": "CommaDelimitedList",
    "Default": "10.0.48.0/24, 10.0.112.0/24, 10.0.176.0/24"
  }
}
```

#### YAML
<a name="parameters-section-structure-example-4.yaml"></a>

```
Parameters: 
  DbSubnetIpBlocks: 
    Description: "Comma-delimited list of three CIDR blocks"
    Type: CommaDelimitedList
    Default: "10.0.48.0/24, 10.0.112.0/24, 10.0.176.0/24"
```

### 从逗号分隔列表参数返回值
<a name="parameters-section-structure-example-5"></a>

要引用以逗号分隔的参数列表中的特定值，请在模板的 `Resources` 部分中使用 `Fn::Select` 内置函数。可传递所需对象的索引值以及对象列表，如以下示例所示。

#### JSON
<a name="parameters-section-structure-example-5.json"></a>

```
{
    "Parameters": {
        "VPC": {
            "Type": "String",
            "Default": "vpc-123456"
        },
        "VpcAzs": {
            "Type": "CommaDelimitedList",
            "Default": "us-west-2a, us-west-2b, us-west-2c"
        },
        "DbSubnetIpBlocks": {
            "Type": "CommaDelimitedList",
            "Default": "172.16.0.0/26, 172.16.0.64/26, 172.16.0.128/26"
        }
    },
    "Resources": {
        "DbSubnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Fn::Select": [
                      0,
                      { 
                        "Ref": "VpcAzs" 
                      }
                   ]
                },
                "VpcId": {
                    "Ref": "VPC"
                },
                "CidrBlock": {
                    "Fn::Select": [
                        0,
                        { "Ref": "DbSubnetIpBlocks" }
                    ]
                }
            }
        },
        "DbSubnet2": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Fn::Sub": [
                        "${AWS::Region}${AZ}",
                        {
                            "AZ": {
                                "Fn::Select": [
                                    1,
                                    { "Ref": "VpcAzs" }
                                ]
                            }
                        }
                    ]
                },
                "VpcId": {
                    "Ref": "VPC"
                },
                "CidrBlock": {
                    "Fn::Select": [
                        1,
                        { "Ref": "DbSubnetIpBlocks" }
                    ]
                }
            }
        },
        "DbSubnet3": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Fn::Sub": [
                        "${AWS::Region}${AZ}",
                        {
                            "AZ": {
                                "Fn::Select": [
                                    2,
                                    { "Ref": "VpcAzs" }
                                ]
                            }
                        }
                    ]
                },
                "VpcId": {
                    "Ref": "VPC"
                },
                "CidrBlock": {
                    "Fn::Select": [
                        2,
                        { "Ref": "DbSubnetIpBlocks" }
                    ]
                }
            }
        }
    }
}
```

#### YAML
<a name="parameters-section-structure-example-5.yaml"></a>

```
Parameters:
  VPC:
    Type: String
    Default: vpc-123456
  VpcAzs:
    Type: CommaDelimitedList
    Default: us-west-2a, us-west-2b, us-west-2c
  DbSubnetIpBlocks:
    Type: CommaDelimitedList
    Default: 172.16.0.0/26, 172.16.0.64/26, 172.16.0.128/26
Resources:
  DbSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 0 
        - !Ref VpcAzs
      VpcId: !Ref VPC
      CidrBlock: !Select
        - 0
        - !Ref DbSubnetIpBlocks
  DbSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub
        - ${AWS::Region}${AZ}
        - AZ: !Select
            - 1
            - !Ref VpcAzs
      VpcId: !Ref VPC
      CidrBlock: !Select
        - 1
        - !Ref DbSubnetIpBlocks
  DbSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub
        - ${AWS::Region}${AZ}
        - AZ: !Select
            - 2
            - !Ref VpcAzs
      VpcId: !Ref VPC
      CidrBlock: !Select
        - 2
        - !Ref DbSubnetIpBlocks
```

## 相关资源
<a name="parameters-section-structure-related-resources"></a>

CloudFormation 还支持使用动态引用来动态指定属性值。例如，您可能需要引用存储在 Systems Manager Parameter Store 中的安全字符串。有关更多信息，请参阅 [使用动态引用获取存储在其他服务中的值](dynamic-references.md)。

您也可以在 `Ref` 或 `Sub` 函数中使用伪参数来动态填充值。有关更多信息，请参阅 [使用伪参数获取 AWS 值](pseudo-parameter-reference.md)。

# CloudFormation 模板 Outputs 语法
<a name="outputs-section-structure"></a>

可选的 `Outputs` 部分用于声明堆栈的输出值。这些输出值可以通过多种方式使用：
+ **捕获与资源有关的重要信息** – 通过输出可以方便地捕获与资源有关的重要信息。例如，您可以输出堆栈的 S3 存储桶名称以使该存储桶更容易找到。可以在 CloudFormation 控制台的**输出**选项卡中或使用 [describe-stacks](service_code_examples.md#describe-stacks-sdk) CLI 命令查看输出值。
+ **跨堆栈引用** – 您可以将输出值导入其他堆栈，以便[在堆栈之间创建引用](using-cfn-stack-exports.md)。当您需要跨多个堆栈共享资源或配置时，这会非常实用。

**重要**  
CloudFormation 不会对 `Outputs` 部分中包含的任何信息进行编辑或模糊处理。我们强烈建议您不要使用此部分输出敏感信息，例如密码或密钥。  
堆栈操作完成后，输出值可用。当堆栈状态处于任何 `IN_PROGRESS` [状态](view-stack-events.md#cfn-console-view-stack-data-resources-status-codes)时，堆栈输出值都不可用。我们不建议在服务运行时和堆栈输出值之间建立依赖关系，因为输出值可能并非始终都可用。

## 语法
<a name="outputs-section-syntax"></a>

`Outputs` 部分包括键名称 `Outputs`。您最多可在一个模板中声明 200 个输出。

以下示例演示了 `Outputs` 部分的结构。

### JSON
<a name="outputs-section-structure-syntax.json"></a>

使用括号将所有输出声明括起来。使用逗号分隔多个输出。

```
"Outputs" : {
  "OutputLogicalID" : {
    "Description" : "Information about the value",
    "Value" : "Value to return",
    "Export" : {
      "Name" : "Name of resource to export"
    }
  }
}
```

### YAML
<a name="outputs-section-structure-syntax.yaml"></a>

```
Outputs:
  OutputLogicalID:
    Description: Information about the value
    Value: Value to return
    Export:
      Name: Name of resource to export
```

### 输出字段
<a name="outputs-section-structure-output-fields"></a>

`Outputs` 部分包含以下字段。

**逻辑 ID（也称为*逻辑名称*）**  
当前输出的标识符。逻辑 ID 必须为字母数字（`a–z`、`A–Z` 和 `0–9`），并且在模板中具有唯一性。

**`Description`（可选）**  
一个描述输出类型的 `String` 类型。描述声明的值必须是长度介于 0 和 1024 个字节之间的文字字符串。您无法使用参数或函数来指定描述。

**`Value`（必需）**  
[describe-stacks](service_code_examples.md#describe-stacks-sdk) 命令返回的属性值。输出值可以包括文字、参数引用、伪参数、映射值或内置函数。

**`Export`（可选）**  
要为跨堆栈引用导出的资源输出的名称。  
您可使用内部函数自定义导出的 `Name` 值。  
有关更多信息，请参阅 [获取从已部署的 CloudFormation 堆栈导出的输出](using-cfn-stack-exports.md)。

要将条件与输出关联，请在模板的 [Conditions](conditions-section-structure.md) 部分中定义条件。

## 示例
<a name="outputs-section-structure-examples"></a>

以下示例说明了堆栈输出的工作原理。

**Topics**
+ [堆栈输出](#outputs-section-structure-examples-stack-output)
+ [使用 `Fn::Sub` 自定义导出名称](#outputs-section-structure-examples-cross-stack)
+ [使用 `Fn::Join` 自定义导出名称](#outputs-section-structure-examples-join-export-name)
+ [返回使用 `Fn::Join` 构造的 URL](#outputs-section-structure-examples-join-export-url)

### 堆栈输出
<a name="outputs-section-structure-examples-stack-output"></a>

在以下示例中，仅当 `BackupLoadBalancerDNSName` 条件为 true 时，名为 `BackupLoadBalancer` 的输出才返回逻辑 ID 为 `CreateProdResources` 的资源的 DNS 名称。名为 `InstanceID` 的输出会返回逻辑 ID 为 `EC2Instance` 的 EC2 实例的 ID。

#### JSON
<a name="outputs-section-structure-example.json"></a>

```
"Outputs" : {
  "BackupLoadBalancerDNSName" : {
    "Description": "The DNSName of the backup load balancer",  
    "Value" : { "Fn::GetAtt" : [ "BackupLoadBalancer", "DNSName" ]},
    "Condition" : "CreateProdResources"
  },
  "InstanceID" : {
    "Description": "The Instance ID",  
    "Value" : { "Ref" : "EC2Instance" }
  }
}
```

#### YAML
<a name="outputs-section-structure-example.yaml"></a>

```
Outputs:
  BackupLoadBalancerDNSName:
    Description: The DNSName of the backup load balancer
    Value: !GetAtt BackupLoadBalancer.DNSName
    Condition: CreateProdResources
  InstanceID:
    Description: The Instance ID
    Value: !Ref EC2Instance
```

### 使用 `Fn::Sub` 自定义导出名称
<a name="outputs-section-structure-examples-cross-stack"></a>

在以下示例中，名为 `StackVPC` 的输出返回 VPC 的 ID，然后在堆栈名称中附加 `VPCID` 导出跨堆栈引用的值。

#### JSON
<a name="outputs-section-structure-cross-stack-example.json"></a>

```
"Outputs" : {
  "StackVPC" : {
    "Description" : "The ID of the VPC",
    "Value" : { "Ref" : "MyVPC" },
    "Export" : {
      "Name" : {"Fn::Sub": "${AWS::StackName}-VPCID" }
    }
  }
}
```

#### YAML
<a name="outputs-section-structure-cross-stack-example.yaml"></a>

```
Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCID"
```

有关 `Fn::Sub` 函数的更多信息，请参阅[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html)。

### 使用 `Fn::Join` 自定义导出名称
<a name="outputs-section-structure-examples-join-export-name"></a>

还可以使用 `Fn::Join` 函数以根据参数、资源属性和其他字符串来构造值。

以下示例使用 `Fn::Join` 函数而不是 `Fn::Sub` 函数，自定义导出名称。示例 `Fn::Join` 函数将冒号用作分隔符，连接堆栈名称与名称 `VPCID`。

#### JSON
<a name="outputs-section-structure-join-export-name-example.json"></a>

```
"Outputs" : {
  "StackVPC" : {
    "Description" : "The ID of the VPC",
    "Value" : { "Ref" : "MyVPC" },
    "Export" : {
      "Name" : { "Fn::Join" : [ ":", [ { "Ref" : "AWS::StackName" }, "VPCID" ] ] }
    }
  }
}
```

#### YAML
<a name="outputs-section-structure-join-export-name-example.yaml"></a>

```
Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", VPCID ] ]
```

有关 `Fn::Join` 函数的更多信息，请参阅[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html)。

### 返回使用 `Fn::Join` 构造的 URL
<a name="outputs-section-structure-examples-join-export-url"></a>

在以下用于创建 WordPress 网站的模板示例中，`InstallURL` 是 `Fn::Join` 函数调用返回的字符串，该字符串将 `http://`、资源 `ElasticLoadBalancer` 的 DNS 名称和 `/wp-admin/install.php` 连接起来。该输出值可能会与以下值相似：

```
http://mywptests-elasticl-1gb51l6sl8y5v-206169572.aws-region.elb.amazonaws.com/wp-admin/install.php
```

#### JSON
<a name="outputs-section-structure-examples-join-export-url.json"></a>

```
{
    "Outputs": {
        "InstallURL": {
            "Value": {
                "Fn::Join": [
                    "",
                    [
                        "http://",
                        {
                            "Fn::GetAtt": [
                                "ElasticLoadBalancer",
                                "DNSName"
                            ]
                        },
                        "/wp-admin/install.php"
                    ]
                ]
            },
            "Description": "Installation URL of the WordPress website"
        }
    }
}
```

#### YAML
<a name="outputs-section-structure-examples-join-export-url.yaml"></a>

```
Outputs:
  InstallURL:
    Value: !Join 
      - ''
      - - 'http://'
        - !GetAtt 
          - ElasticLoadBalancer
          - DNSName
        - /wp-admin/install.php
    Description: Installation URL of the WordPress website
```

有关 `Fn::Join` 函数的更多信息，请参阅[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html)。

# CloudFormation 模板 Mappings 语法
<a name="mappings-section-structure"></a>

您可以借助可选的 `Mappings` 部分来创建键值对，从而可以根据特定条件或依赖项指定值。

`Mappings` 部分的一个常见应用场景是根据部署堆栈的 AWS 区域来设置值。这可以通过使用 `AWS::Region` 伪参数来实现。`AWS::Region` 伪参数是 CloudFormation 用来解析到创建堆栈所在区域的值。在创建堆栈时，CloudFormation 解析了这些伪参数。

要检索映射中的值，您可以在模板的 `Resources` 部分中使用 `Fn::FindInMap` 内置函数。

## 语法
<a name="mappings-section-structure-syntax"></a>

`Mappings` 部分使用以下语法：

### JSON
<a name="mappings-section-structure-syntax.json"></a>

```
"Mappings" : {
  "MappingLogicalName" : {
    "Key1" : {
      "Name" : "Value1"
    },
    "Key2" : {
      "Name" : "Value2"
    },
    "Key3" : {
      "Name" : "Value3"
    }
  }
}
```

### YAML
<a name="mappings-section-structure-syntax.yaml"></a>

```
Mappings: 
  MappingLogicalName: 
    Key1: 
      Name: Value1
    Key2: 
      Name: Value2
    Key3: 
      Name: Value3
```
+ `MappingLogicalName` 是映射的逻辑名称。
+ 在映射中，每个映射是一个键，后跟另一个映射。
+ 键必须是名称/值对映射，且在映射中必须唯一。
+ 名值对是一个标签，该值是用来映射的。您可以通过给值命名以将多组值映射到密钥中。
+ 映射中的键必须为文字字符串。
+ 值可以是 `String` 或 `List` 类型。

**注意**  
不得在 `Mappings` 部分包含参数、伪参数或内部函数。  
如果堆栈目前未使用映射中的值，则无法单独更新映射。您必须包含添加、修改或删除资源的更改。

## 示例
<a name="mappings-section-structure-examples"></a>

**Topics**
+ [基本映射](#mappings-section-structure-basic-example)
+ [带有多个值的映射](#mappings-section-structure-multiple-values-example)
+ [从映射返回值](#mappings-section-structure-return-value-example)
+ [输入参数和 `Fn::FindInMap`](#mappings-section-structure-input-parameter-example)

### 基本映射
<a name="mappings-section-structure-basic-example"></a>

以下示例显示的是带映射 `Mappings` 的 `RegionToInstanceType` 部分，该映射包含五个映射到含单字符串值的名称-值对的密钥。密钥为区域名称。每个名称值对都是该键所表示区域内的 T 系列中可用的一种实例类型。名称值对中有一个名称（示例中的 `InstanceType`）和一个值。

#### JSON
<a name="mappings-section-structure-basic-example.json"></a>

```
"Mappings" : {
  "RegionToInstanceType" : {
    "us-east-1"      : { "InstanceType" : "t2.micro" },
    "us-west-1"      : { "InstanceType" : "t2.micro" },
    "eu-west-1"      : { "InstanceType" : "t2.micro" },
    "eu-north-1"     : { "InstanceType" : "t3.micro" },
    "me-south-1"     : { "InstanceType" : "t3.micro" }
  }
}
```

#### YAML
<a name="mappings-section-structure-basic-example.yaml"></a>

```
Mappings:
  RegionToInstanceType:
    us-east-1:
      InstanceType: t2.micro
    us-west-1:
      InstanceType: t2.micro
    eu-west-1:
      InstanceType: t2.micro
    eu-north-1:
      InstanceType: t3.micro
    me-south-1:
      InstanceType: t3.micro
```

### 带有多个值的映射
<a name="mappings-section-structure-multiple-values-example"></a>

以下示例中的区域键映射到两组值：一组名为 `MyAMI1`，另一组为 `MyAMI2`。

**注意**  
这些示例中显示的 AMI ID 是演示用的占位符。应尽量考虑使用 AWS Systems Manager 参数的动态引用，作为 `Mappings` 部分的替代方案。要避免每次要使用的 AMI 发生更改时都使用新 ID 来更新所有模板，请在创建或更新堆栈时使用 AWS Systems Manager 参数来检索最新 AMI ID。常用 AMI 的最新版本也可作为 Systems Manager 中的公有参数提供。有关更多信息，请参阅[使用动态引用获取存储在其他服务中的值](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html)。

#### JSON
<a name="mappings-section-structure-multiple-values-example"></a>

```
"Mappings" : {
  "RegionToAMI" : {
    "us-east-1"        : { "MyAMI1" : "ami-12345678901234567", "MyAMI2" : "ami-23456789012345678" },
    "us-west-1"        : { "MyAMI1" : "ami-34567890123456789", "MyAMI2" : "ami-45678901234567890" },
    "eu-west-1"        : { "MyAMI1" : "ami-56789012345678901", "MyAMI2" : "ami-67890123456789012" },
    "ap-southeast-1"   : { "MyAMI1" : "ami-78901234567890123", "MyAMI2" : "ami-89012345678901234" },
    "ap-northeast-1"   : { "MyAMI1" : "ami-90123456789012345", "MyAMI2" : "ami-01234567890123456" }
  }
}
```

#### YAML
<a name="mappings-section-structure-multiple-values-example.yaml"></a>

```
Mappings:
  RegionToAMI:
    us-east-1:
      MyAMI1: ami-12345678901234567
      MyAMI2: ami-23456789012345678
    us-west-1:
      MyAMI1: ami-34567890123456789
      MyAMI2: ami-45678901234567890
    eu-west-1:
      MyAMI1: ami-56789012345678901
      MyAMI2: ami-67890123456789012
    ap-southeast-1:
      MyAMI1: ami-78901234567890123
      MyAMI2: ami-89012345678901234
    ap-northeast-1:
      MyAMI1: ami-90123456789012345
      MyAMI2: ami-01234567890123456
```

### 从映射返回值
<a name="mappings-section-structure-return-value-example"></a>

您可以使用 `Fn::FindInMap` 函数根据指定的密钥返回命名的值。以下示例模板包含由 `FindInMap` 函数分配其 `InstanceType` 属性的 Amazon EC2 资源。`FindInMap` 函数将键指定为创建堆栈的 AWS 区域（使用 `AWS::Region` 伪参数），并将 `InstanceType` 指定为要映射到的值的名称。`ImageId` 使用 Systems Manager 参数动态检索最新的 Amazon Linux 2 AMI。有关伪参数的更多信息，请参阅[使用伪参数获取 AWS 值](pseudo-parameter-reference.md)。

#### JSON
<a name="mappings-section-structure-return-value-example.json"></a>

```
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Mappings" : {
    "RegionToInstanceType" : {
      "us-east-1"      : { "InstanceType" : "t2.micro" },
      "us-west-1"      : { "InstanceType" : "t2.micro" },
      "eu-west-1"      : { "InstanceType" : "t2.micro" },
      "eu-north-1"     : { "InstanceType" : "t3.micro" },
      "me-south-1"     : { "InstanceType" : "t3.micro" }
    }
  },
  "Resources" : {
    "myEC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
        "InstanceType" : { "Fn::FindInMap" : [ "RegionToInstanceType", { "Ref" : "AWS::Region" }, "InstanceType" ]}
      }
    }
  }
}
```

#### YAML
<a name="mappings-section-structure-return-value-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Mappings: 
  RegionToInstanceType: 
    us-east-1:
      InstanceType: t2.micro
    us-west-1:
      InstanceType: t2.micro
    eu-west-1:
      InstanceType: t2.micro
    eu-north-1:
      InstanceType: t3.micro
    me-south-1:
      InstanceType: t3.micro
Resources: 
  myEC2Instance: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
      InstanceType: !FindInMap [RegionToInstanceType, !Ref 'AWS::Region', InstanceType]
```

### 输入参数和 `Fn::FindInMap`
<a name="mappings-section-structure-input-parameter-example"></a>

以下示例模板显示如何使用多个映射来创建 EC2 实例。该模板使用嵌套映射，根据目标 AWS 区域 和环境类型（`Dev` 或 `Prod`）自动选择相应的实例类型和安全组。模板还使用 Systems Manager 参数来动态检索最新的 Amazon Linux 2 AMI。

#### JSON
<a name="mappings-section-structure-input-parameter-example.json"></a>

```
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Parameters" : {
    "EnvironmentType" : {
      "Description" : "The environment type (Dev or Prod)",
      "Type" : "String",
      "Default" : "Dev",
      "AllowedValues" : [ "Dev", "Prod" ]
    }
  },
  "Mappings" : {
    "RegionAndEnvironmentToInstanceType" : {
      "us-east-1"        : { "Dev" : "t3.micro", "Prod" : "c5.large" },
      "us-west-1"        : { "Dev" : "t2.micro", "Prod" : "m5.large" }
    },
    "RegionAndEnvironmentToSecurityGroup" : {
      "us-east-1"        : { "Dev" : "sg-12345678", "Prod" : "sg-abcdef01" },
      "us-west-1"        : { "Dev" : "sg-ghijkl23", "Prod" : "sg-45678abc" }
    }
  },
  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
        "InstanceType" : { "Fn::FindInMap": [ "RegionAndEnvironmentToInstanceType", { "Ref": "AWS::Region" }, { "Ref": "EnvironmentType" } ]},
        "SecurityGroupIds" : [{ "Fn::FindInMap" : [ "RegionAndEnvironmentToSecurityGroup", { "Ref" : "AWS::Region" }, { "Ref" : "EnvironmentType" } ]}]
      }
    }
  }
}
```

#### YAML
<a name="mappings-section-structure-input-parameter-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EnvironmentType: 
    Description: The environment type (Dev or Prod)
    Type: String
    Default: Dev
    AllowedValues: 
      - Dev
      - Prod
Mappings:
  RegionAndEnvironmentToInstanceType:
    us-east-1: 
      Dev: t3.micro
      Prod: c5.large
    us-west-1: 
      Dev: t2.micro
      Prod: m5.large
  RegionAndEnvironmentToSecurityGroup: 
    us-east-1: 
      Dev: sg-12345678
      Prod: sg-abcdef01
    us-west-1: 
      Dev: sg-ghijkl23
      Prod: sg-45678abc
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
      InstanceType: !FindInMap [RegionAndEnvironmentToInstanceType, !Ref 'AWS::Region', !Ref EnvironmentType]
      SecurityGroupIds:
        - !FindInMap [RegionAndEnvironmentToSecurityGroup, !Ref 'AWS::Region', !Ref EnvironmentType]
```

## 相关资源
<a name="mappings-section-related-resources"></a>

在开发使用 `Fn::FindInMap` 函数的模板时，这些相关主题可能对您有所帮助。
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-findinmap.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-findinmap.html)
+ [Fn::FindInMap 增强功能](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-findinmap-enhancements.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html)

# CloudFormation 模板 Metadata 语法
<a name="metadata-section-structure"></a>

`Metadata` 使用 JSON 或 YAML 对象存储其他信息。您可以在模板中使用的模板级元数据类型包括：

自定义元数据  
存储用户定义的键值对。例如，您可以提供其他信息，这些信息不影响资源创建，但可以提供有关基础设施、团队或部署细节的其他背景信息。

`AWS::CloudFormation::Interface`  
定义在 CloudFormation 控制台中显示输入参数时的分组和排序。默认情况下，CloudFormation 控制台按照参数的逻辑 ID 的字母顺序排序。

`AWS::CloudFormation::Designer`  
CloudFormation Designer (Designer) 已于 2025 年 2 月 5 日终止使用。



**重要**  
堆栈更新期间，您无法更新 `Metadata` 部分本身。您只能在包括添加、修改或删除资源的更改时更新它。  
CloudFormation 不会转换、修改或编辑您在 `Metadata` 部分中包含的任何信息。因此，我们强烈建议您不要使用此部分存储敏感信息，例如密码或密钥。

## 语法
<a name="metadata-section-structure-syntax"></a>

要在 CloudFormation 模板中声明自定义元数据，请使用以下语法：

### JSON
<a name="metadata-section-structure-syntax.json"></a>

```
"Metadata" : {
  "Instances" : {"Description" : "Information about the instances"},
  "Databases" : {"Description" : "Information about the databases"}
}
```

### YAML
<a name="metadata-section-structure-syntax.yaml"></a>

```
Metadata:
  Instances:
    Description: "Information about the instances"
  Databases: 
    Description: "Information about the databases"
```

有关 `AWS::CloudFormation::Interface` 的语法，请参阅 [使用 `AWS::CloudFormation::Interface` 元数据整理 CloudFormation 参数](aws-cloudformation-interface.md)。

# 使用 `AWS::CloudFormation::Interface` 元数据整理 CloudFormation 参数
<a name="aws-cloudformation-interface"></a>

`AWS::CloudFormation::Interface` 是一种元数据键，用于定义参数在 CloudFormation 控制台中的分组和排序方式。在控制台中创建或更新堆栈时，默认情况下控制台会依照输入参数的逻辑 ID 的字母顺序将其列出。您可以借助此键定义自己的参数分组和排序方法，以便用户高效地指定参数值。例如，您可以将所有 EC2 相关的参数放到一个组中、将所有 VPC 相关的参数放到另一个组中。

在元数据键中，您可以指定要创建的组、每个组包含的参数以及控制台在其分组中显示各个参数时的顺序。

您还可以定义参数标签。标签是控制台显示的易记名称或描述，以代替参数的逻辑 ID。标签可帮助用户了解为每个参数指定的值。例如，您可以将 `KeyPair` 参数标记为 `Select an EC2 key pair`。

在元数据键中引用的所有参数都必须在模板的 `Parameters` 部分中声明。

**注意**  
仅 CloudFormation 控制台使用 `AWS::CloudFormation::Interface` 元数据键。AWS CLI 和 API 调用不使用此键。

## 语法
<a name="aws-resource-cloudformation-interface-syntax"></a>

要在 CloudFormation 模板中声明此实体，请使用以下语法：

### JSON
<a name="aws-resource-cloudformation-interface-syntax.json"></a>

```
"Metadata" : {
  "AWS::CloudFormation::Interface" : {
    "ParameterGroups": [
      {
        "Label": {
          "default": "Group Label"
        },
        "Parameters": [
          "Parameter1",
          "Parameter2"
        ]
      }
    ],
    "ParameterLabels": {
      "Parameter1": {
        "default": "Friendly Name for Parameter1"
      }
    }
  }
}
```

### YAML
<a name="aws-resource-cloudformation-interface-syntax.yaml"></a>

```
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Group Label
        Parameters:
          - Parameter1
          - Parameter2
    ParameterLabels:
      Parameter1:
        default: Friendly Name for Parameter1
```

## 属性
<a name="w2aac11c23c29c17c17"></a>

`ParameterGroups`  
参数组类型的列表、指定组名称的地方、每个组中的参数以及参数的显示顺序。  
*必需*：否    
`Label`  
参数组的名称。  
*必需*：否  
`default`  
CloudFormation 控制台用于命名参数组的默认标签。  
*必需*：否  
*类型*：字符串  
`Parameters`  
要包含在组中的参数逻辑 ID (区分大小写) 的列表。参数必须已在模板的 `Parameters` 部分中定义。参数只能包含在一个参数组中。  
控制台在 `Other parameters` 组中按字母顺序列出未与参数组关联的参数。  
*必需*：否  
*类型*：字符串值列表

`ParameterLabels`  
创建或更新堆栈时，CloudFormation 控制台显示的参数与易记名称的映射。  
*必需*：否    
参数标签  
参数的标签。标签定义在创建或更新堆栈时 CloudFormation 控制台在 **Specify Parameters** 页面上显示的易记名称或描述。参数标签必须为已在模板的 `Parameters` 部分中声明的有效参数的逻辑 ID（区分大小写）。  
*必需*：否  
`default`  
CloudFormation 控制台用于命名参数的默认标签。  
*必需*：否  
*类型*：字符串

## 示例
<a name="w2aac11c23c29c17c19"></a>

以下示例定义了两个参数组：`Network Configuration` 和 `Amazon EC2 Configuration`。`Network Configuration` 组包含 `VPCID`、`SubnetId` 和 `SecurityGroupID` 参数 (在模板的 `Parameters` 部分中定义，未显示)。参数的列出顺序定义了控制台显示这些参数的顺序，以 `VPCID` 参数开始。以下示例以相似方式分组和排序 `Amazon EC2 Configuration` 参数。

该示例还为 `VPCID` 参数定义了一个标签。控制台将显示**应将此元素部署到哪个 VPC？**，而不是参数的逻辑 ID (`VPCID`)。

### JSON
<a name="aws-cloudformation-interface-example.json"></a>

```
"Metadata" : {
  "AWS::CloudFormation::Interface" : {
    "ParameterGroups" : [
      {
        "Label" : { "default" : "Network Configuration" },
        "Parameters" : [ "VPCID", "SubnetId", "SecurityGroupID" ]
      },
      {
        "Label" : { "default":"Amazon EC2 Configuration" },
        "Parameters" : [ "InstanceType", "KeyName" ]
      }
    ],
    "ParameterLabels" : {
      "VPCID" : { "default" : "Which VPC should this be deployed to?" }
    }
  }
}
```

### YAML
<a name="aws-cloudformation-interface-example.yaml"></a>

```
Metadata: 
  AWS::CloudFormation::Interface: 
    ParameterGroups: 
      - Label: 
          default: "Network Configuration"
        Parameters: 
          - VPCID
          - SubnetId
          - SecurityGroupID
      - Label: 
          default: "Amazon EC2 Configuration"
        Parameters: 
          - InstanceType
          - KeyName
    ParameterLabels: 
      VPCID: 
        default: "Which VPC should this be deployed to?"
```

### 控制台中的参数组
<a name="w2aac11c23c29c17c19c11"></a>

下图展示了使用本示例中的元数据键后，在创建或更新堆栈时控制台如何显示参数组：**控制台中的参数组** 

![\[显示该示例的参数组的控制台。\]](http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/images/console-create-stack-parameter-groups.png)


# CloudFormation 模板 Rules 语法
<a name="rules-section-structure"></a>

`Rules` 部分是 CloudFormation 模板的可选部分，可启用自定义验证逻辑。如果包含，此部分包含在 CloudFormation 创建或更新任何资源之前验证参数值的规则函数。

当标准参数约束不足时，规则非常有用。例如，如果启用了 SSL，则必须同时提供证书和域名。规则可以确保满足这些依赖关系。

## 语法
<a name="template-constraint-rules-syntax"></a>

`Rules` 部分使用以下语法：

### JSON
<a name="rules-section-structure-syntax.json"></a>

模板的`Rules` 部分由后跟冒号的密钥名称 `Rules` 组成。必须使用括号将所有规则声明括起来。如果您声明多个规则，则可用逗号将它们分隔开。对于每个规则，您必须声明一个用引号引起来的逻辑名称，后跟冒号以及将规则条件和断言括起来的括号。

```
{
    "Rules": {
        "LogicalRuleName1": {
            "RuleCondition": {
                "rule-specific intrinsic function": "Value"
            },
            "Assertions": [
                {
                    "Assert": {
                        "rule-specific intrinsic function": "Value"
                    },
                    "AssertDescription": "Information about this assert"
                },
                {
                    "Assert": {
                        "rule-specific intrinsic function": "Value"
                    },
                    "AssertDescription": "Information about this assert"
                }
            ]
        },
        "LogicalRuleName2": {
            "Assertions": [
                {
                    "Assert": {
                        "rule-specific intrinsic function": "Value"
                    },
                    "AssertDescription": "Information about this assert"
                }
            ]
        }
    }
}
```

### YAML
<a name="rules-section-structure-syntax.yaml"></a>

```
Rules:
  LogicalRuleName1:
    RuleCondition:
      rule-specific intrinsic function: Value
    Assertions:
      - Assert:
          rule-specific intrinsic function: Value
        AssertDescription: Information about this assert
      - Assert:
          rule-specific intrinsic function: Value
        AssertDescription: Information about this assert
  LogicalRuleName2:
    Assertions:
      - Assert:
          rule-specific intrinsic function: Value
        AssertDescription: Information about this assert
```

### 规则字段
<a name="rules-section-fields"></a>

`Rules` 部分包含以下字段。

**逻辑 ID（也称为*逻辑名称*）**  
每条规则的唯一标识符。

**`RuleCondition`（可选）**  
确定规则生效时间的属性。如果您未定义规则条件，则规则的断言始终生效。对于每个规则，您只能定义一个规则条件。

**`Assertions`（必需）**  
指定特定参数可接受值的一条或多条语句。

**`Assert`**  
必须计算为 `true` 的条件。

**`AssertDescription`**  
断言失败时显示的消息。

## 特定于规则的内部函数
<a name="rules-specific-intrinsic-section-structure"></a>

要定义规则，您必须使用*特定于规则的函数*，只能在模板的 `Rules` 部分中使用这些函数。虽然可以嵌套这些函数，但规则条件或断言的最终结果必须为 `true` 或 `false`。

以下规则函数可用：
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-contains](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-contains)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberequals](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberequals)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberin](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberin)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-refall](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-refall)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueof](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueof)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueofall](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueofall)

这些函数在规则的条件或断言中使用。条件属性确定 CloudFormation 是否应用断言。如果条件的计算结果为 `true`，则 CloudFormation 将评估断言以验证在创建或更新预配置产品时参数值是否有效。如果参数值无效，则 CloudFormation 不会创建或更新堆栈。如果条件的计算结果为 `false`，则 CloudFormation 不会检查参数值并继续堆栈操作。

## 示例
<a name="template-constraint-rules-example"></a>

**Topics**
+ [按条件验证参数值](#template-constraint-rules-example-verify)
+ [交叉参数验证](#template-cross-parameter-rules-example)

### 按条件验证参数值
<a name="template-constraint-rules-example-verify"></a>

在以下示例中，两个规则检查 `InstanceType` 参数的值。根据环境参数（`test` 或 `prod`）的值，用户必须为 `InstanceType` 参数指定 `t3.medium` 或 `t3.large`。必须在同一模板的 `InstanceType` 部分中声明 `Environment` 和 `Parameters` 参数。

#### JSON
<a name="rules-section-example-conditionally-verify.json"></a>

```
{
  "Rules": {
    "testInstanceType": {
      "RuleCondition": {
        "Fn::Equals": [
          {"Ref": "Environment"},
          "test"
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Contains": [
              ["t3.medium"],
              {"Ref": "InstanceType"}
            ]
          },
          "AssertDescription": "For a test environment, the instance type must be t3.medium"
        }
      ]
    },
    "prodInstanceType": {
      "RuleCondition": {
        "Fn::Equals": [
          {"Ref": "Environment"},
          "prod"
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Contains": [
              ["t3.large"],
              {"Ref": "InstanceType"}
            ]
          },
          "AssertDescription": "For a production environment, the instance type must be t3.large"
        }
      ]
    }
  }
}
```

#### YAML
<a name="rules-section-example-conditionally-verify.yaml"></a>

```
Rules:
  testInstanceType:
    RuleCondition: !Equals 
      - !Ref Environment
      - test
    Assertions:
      - Assert:
          'Fn::Contains':
            - - t3.medium
            - !Ref InstanceType
        AssertDescription: 'For a test environment, the instance type must be t3.medium'
  prodInstanceType:
    RuleCondition: !Equals 
      - !Ref Environment
      - prod
    Assertions:
      - Assert:
          'Fn::Contains':
            - - t3.large
            - !Ref InstanceType
        AssertDescription: 'For a production environment, the instance type must be t3.large'
```

### 交叉参数验证
<a name="template-cross-parameter-rules-example"></a>

以下示例模板演示如何使用规则进行跨参数验证。其创建了一个在负载均衡器背后自动扩缩组上运行的示例网站。根据输入参数，该网站可在端口 80 或 443 上使用。可以将自动扩缩组中的实例配置为在任何端口上侦听（默认为 8888）。

此模板中的规则会在创建堆栈之前验证输入参数。其验证所有子网是否属于指定的 VPC，并确保将 `UseSSL` 参数设置为 `Yes` 时，同时提供 SSL 证书 ARN 和托管区域名称。

**注意**  
如果您通过本模板创建堆栈，则需为使用的 AWS 资源支付相应费用。

#### JSON
<a name="rules-section-example-cross-parameter-validation.json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "VpcId": {
      "Type": "AWS::EC2::VPC::Id",
      "Description": "VpcId of your existing Virtual Private Cloud (VPC)",
      "ConstraintDescription": "must be the VPC Id of an existing Virtual Private Cloud."
    },
    "Subnets": {
      "Type": "List<AWS::EC2::Subnet::Id>",
      "Description": "The list of SubnetIds in your Virtual Private Cloud (VPC)",
      "ConstraintDescription": "must be a list of at least two existing subnets associated with at least two different availability zones."
    },
    "InstanceType": {
      "Description": "WebServer EC2 instance type",
      "Type": "String",
      "Default": "t2.micro",
      "AllowedValues": ["t2.micro", "t3.micro"],
      "ConstraintDescription": "must be a valid EC2 instance type."
    },
    "KeyName": {
      "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type": "AWS::EC2::KeyPair::KeyName",
      "ConstraintDescription": "must be the name of an existing EC2 KeyPair."
    },
    "SSHLocation": {
      "Description": "The IP address range that can be used to SSH to the EC2 instances",
      "Type": "String",
      "MinLength": "9",
      "MaxLength": "18",
      "Default": "0.0.0.0/0",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
    },
    "UseSSL": {
      "AllowedValues": ["Yes", "No"],
      "Default": "No",
      "Description": "Select \"Yes\" to implement SSL, \"No\" to skip (default).",
      "Type": "String"
    },
    "ALBSSLCertificateARN": {
      "Default": "",
      "Description": "[Optional] The ARN of the SSL certificate to be used for the Application Load Balancer",
      "Type": "String"
    },
    "HostedZoneName": {
      "AllowedPattern": "^$|(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$",
      "Default": "",
      "Description": "[Optional] The domain name of a valid Hosted Zone on AWS.",
      "Type": "String"
    }
  },
  "Conditions": {
    "UseALBSSL": {"Fn::Equals": [{"Ref": "UseSSL"}, "Yes"]}
  },
  "Rules": {
    "SubnetsInVPC": {
      "Assertions": [
        {
          "Assert": {"Fn::EachMemberEquals": [{"Fn::ValueOf": ["Subnets", "VpcId"]}, {"Ref": "VpcId"}]},
          "AssertDescription": "All subnets must be in the VPC"
        }
      ]
    },
    "ValidateHostedZone": {
      "RuleCondition": {"Fn::Equals": [{"Ref": "UseSSL"}, "Yes"]},
      "Assertions": [
        {
          "Assert": {"Fn::Not": [{"Fn::Equals": [{"Ref": "ALBSSLCertificateARN"}, ""]}]},
          "AssertDescription": "ACM Certificate value cannot be empty if SSL is required"
        },
        {
          "Assert": {"Fn::Not": [{"Fn::Equals": [{"Ref": "HostedZoneName"}, ""]}]},
          "AssertDescription": "Route53 Hosted Zone Name is mandatory when SSL is required"
        }
      ]
    }
  },
  "Resources": {
    "WebServerGroup": {
      "Type": "AWS::AutoScaling::AutoScalingGroup",
      "Properties": {
        "VPCZoneIdentifier": {"Ref": "Subnets"},
        "LaunchTemplate": {
          "LaunchTemplateId": {"Ref": "LaunchTemplate"},
          "Version": {"Fn::GetAtt": ["LaunchTemplate","LatestVersionNumber"]}
        },
        "MinSize": "2",
        "MaxSize": "2",
        "TargetGroupARNs": [{"Ref": "ALBTargetGroup"}]
      },
      "CreationPolicy": {
        "ResourceSignal": {"Timeout": "PT15M"}
      },
      "UpdatePolicy": {
        "AutoScalingRollingUpdate": {
          "MinInstancesInService": "1",
          "MaxBatchSize": "1",
          "PauseTime": "PT15M",
          "WaitOnResourceSignals": true
        }
      }
    },
    "LaunchTemplate": {
      "Type": "AWS::EC2::LaunchTemplate",
      "Metadata": {
        "Comment": "Install a simple application",
        "AWS::CloudFormation::Init": {
          "config": {
            "packages": {"yum": {"httpd": []}},
            "files": {
              "/var/www/html/index.html": {
                "content": {"Fn::Join": ["\n", ["<h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1>"]]},
                "mode": "000644",
                "owner": "root",
                "group": "root"
              },
              "/etc/cfn/cfn-hup.conf": {
                "content": {"Fn::Join": ["", [
                  "[main]\n",
                  "stack=", {"Ref": "AWS::StackId"}, "\n",
                  "region=", {"Ref": "AWS::Region"}, "\n"
                ]]},
                "mode": "000400",
                "owner": "root",
                "group": "root"
              },
              "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                "content": {"Fn::Join": ["", [
                  "[cfn-auto-reloader-hook]\n",
                  "triggers=post.update\n",
                  "path=Resources.LaunchTemplate.Metadata.AWS::CloudFormation::Init\n",
                  "action=/opt/aws/bin/cfn-init -v ",
                  "         --stack ", {"Ref": "AWS::StackName"},
                  "         --resource LaunchTemplate ",
                  "         --region ", {"Ref": "AWS::Region"}, "\n",
                  "runas=root\n"
                ]]},
                "mode": "000400",
                "owner": "root",
                "group": "root"
              }
            },
            "services": {
              "sysvinit": {
                "httpd": {
                  "enabled": "true",
                  "ensureRunning": "true"
                },
                "cfn-hup": {
                  "enabled": "true",
                  "ensureRunning": "true",
                  "files": [
                    "/etc/cfn/cfn-hup.conf",
                    "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                  ]
                }
              }
            }
          }
        }
      },
      "Properties": {
        "LaunchTemplateName": {"Fn::Sub": "${AWS::StackName}-launch-template"},
        "LaunchTemplateData": {
          "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
          "SecurityGroupIds": [{"Ref": "InstanceSecurityGroup"}],
          "InstanceType": {"Ref": "InstanceType"},
          "KeyName": {"Ref": "KeyName"},
          "UserData": {
            "Fn::Base64": {"Fn::Join": ["", [
              "#!/bin/bash\n",
              "yum install -y aws-cfn-bootstrap\n",
              "/opt/aws/bin/cfn-init -v ",
              "         --stack ", {"Ref": "AWS::StackName"},
              "         --resource LaunchTemplate ",
              "         --region ", {"Ref": "AWS::Region"}, "\n",
              "/opt/aws/bin/cfn-signal -e $? ",
              "         --stack ", {"Ref": "AWS::StackName"},
              "         --resource WebServerGroup ",
              "         --region ", {"Ref": "AWS::Region"}, "\n"
            ]]}
          }
        }
      }
    },
    "ELBSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Allow access to the ELB",
        "VpcId": {"Ref": "VpcId"},
        "SecurityGroupIngress": [{
          "Fn::If": [
            "UseALBSSL",
            {
              "IpProtocol": "tcp",
              "FromPort": 443,
              "ToPort": 443,
              "CidrIp": "0.0.0.0/0"
            },
            {
              "IpProtocol": "tcp",
              "FromPort": 80,
              "ToPort": 80,
              "CidrIp": "0.0.0.0/0"
            }
          ]
        }]
      }
    },
    "ApplicationLoadBalancer": {
      "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties": {
        "Subnets": {"Ref": "Subnets"},
        "SecurityGroups": [{"Ref": "ELBSecurityGroup"}]
      }
    },
    "ALBListener": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Properties": {
        "DefaultActions": [{
          "Type": "forward",
          "TargetGroupArn": {"Ref": "ALBTargetGroup"}
        }],
        "LoadBalancerArn": {"Ref": "ApplicationLoadBalancer"},
        "Port": {"Fn::If": ["UseALBSSL", 443, 80]},
        "Protocol": {"Fn::If": ["UseALBSSL", "HTTPS", "HTTP"]},
        "Certificates": [{
          "Fn::If": [
            "UseALBSSL",
            {"CertificateArn": {"Ref": "ALBSSLCertificateARN"}},
            {"Ref": "AWS::NoValue"}
          ]
        }]
      }
    },
    "ALBTargetGroup": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties": {
        "HealthCheckIntervalSeconds": 30,
        "HealthCheckTimeoutSeconds": 5,
        "HealthyThresholdCount": 3,
        "Port": 80,
        "Protocol": "HTTP",
        "UnhealthyThresholdCount": 5,
        "VpcId": {"Ref": "VpcId"}
      }
    },
    "InstanceSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Enable SSH access and HTTP access on the inbound port",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 80,
            "ToPort": 80,
            "SourceSecurityGroupId": {"Fn::Select": [0, {"Fn::GetAtt": ["ApplicationLoadBalancer", "SecurityGroups"]}]}
          },
          {
            "IpProtocol": "tcp",
            "FromPort": 22,
            "ToPort": 22,
            "CidrIp": {"Ref": "SSHLocation"}
          }
        ],
        "VpcId": {"Ref": "VpcId"}
      }
    },
    "RecordSet": {
      "Type": "AWS::Route53::RecordSetGroup",
      "Condition": "UseALBSSL",
      "Properties": {
        "HostedZoneName": {"Fn::Join": ["", [{"Ref": "HostedZoneName"}, "."]]},
        "RecordSets": [{
          "Name": {"Fn::Join": ["", [
            {"Fn::Select": ["0", {"Fn::Split": [".", {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]}]}]},
            ".",
            {"Ref": "HostedZoneName"},
            "."
          ]]},
          "Type": "A",
          "AliasTarget": {
            "DNSName": {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]},
            "EvaluateTargetHealth": true,
            "HostedZoneId": {"Fn::GetAtt": ["ApplicationLoadBalancer", "CanonicalHostedZoneID"]}
          }
        }]
      }
    }
  },
  "Outputs": {
    "URL": {
      "Description": "URL of the website",
      "Value": {"Fn::Join": ["", [
        {"Fn::If": [
          "UseALBSSL",
          {"Fn::Join": ["", [
            "https://",
            {"Fn::Join": ["", [
              {"Fn::Select": ["0", {"Fn::Split": [".", {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]}]}]},
              ".",
              {"Ref": "HostedZoneName"},
              "."
            ]]}
          ]]},
          {"Fn::Join": ["", [
            "http://",
            {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]}
          ]]}
        ]}
      ]]}
    }
  }
}
```

#### YAML
<a name="rules-section-example-syntax.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VpcId of your existing Virtual Private Cloud (VPC)
    ConstraintDescription: must be the VPC Id of an existing Virtual Private Cloud.
  Subnets:
    Type: List<AWS::EC2::Subnet::Id>
    Description: The list of SubnetIds in your Virtual Private Cloud (VPC)
    ConstraintDescription: >-
      must be a list of at least two existing subnets associated with at least
      two different availability zones. They should be residing in the selected
      Virtual Private Cloud.
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t3.micro
    ConstraintDescription: must be a valid EC2 instance type.
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  UseSSL:
    AllowedValues:
      - 'Yes'
      - 'No'
    ConstraintDescription: Select Yes to create a HTTPS Listener
    Default: 'No'
    Description: 'Select "Yes" to implement SSL, "No" to skip (default).'
    Type: String
  ALBSSLCertificateARN:
    Default: ''
    Description: >-
      [Optional] The ARN of the SSL certificate to be used for the Application
      Load Balancer
    Type: String
  HostedZoneName:
    AllowedPattern: >-
      ^$|(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$
    Default: ''
    Description: '[Optional] The domain name of a valid Hosted Zone on AWS.'
    Type: String
Conditions:
  UseALBSSL: !Equals 
    - !Ref UseSSL
    - 'Yes'
Rules:
  SubnetsInVPC:
    Assertions:
      - Assert:
          'Fn::EachMemberEquals':
            - 'Fn::ValueOf':
                - Subnets
                - VpcId
            - Ref: VpcId
        AssertDescription: All subnets must be in the VPC
  ValidateHostedZone:
    RuleCondition: !Equals 
      - !Ref UseSSL
      - 'Yes'
    Assertions:
      - Assert: !Not 
          - !Equals 
            - !Ref ALBSSLCertificateARN
            - ''
        AssertDescription: ACM Certificate value cannot be empty if SSL is required
      - Assert: !Not 
          - !Equals 
            - !Ref HostedZoneName
            - ''
        AssertDescription: Route53 Hosted Zone Name is mandatory when SSL is required
Resources:
  WebServerGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      VPCZoneIdentifier: !Ref Subnets
      LaunchTemplate:
        LaunchTemplateId: !Ref LaunchTemplate
        Version: !GetAtt LaunchTemplate.LatestVersionNumber
      MinSize: '2'
      MaxSize: '2'
      TargetGroupARNs:
        - !Ref ALBTargetGroup
    CreationPolicy:
      ResourceSignal:
        Timeout: PT15M
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: '1'
        MaxBatchSize: '1'
        PauseTime: PT15M
        WaitOnResourceSignals: 'true'
  LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Metadata:
      Comment: Install a simple application
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: !Join 
                - |+
                - - >-
                    <h1>Congratulations, you have successfully launched the AWS
                    CloudFormation sample.</h1>
              mode: '000644'
              owner: root
              group: root
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |-
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.LaunchTemplate.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${AWS::Region}
                runas=root
              mode: '000400'
              owner: root
              group: root
          services:
            sysvinit:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
              cfn-hup:
                enabled: 'true'
                ensureRunning: 'true'
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    Properties:
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData:
        ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
        SecurityGroupIds:
        - !Ref InstanceSecurityGroup
        InstanceType: !Ref InstanceType
        KeyName: !Ref KeyName
        UserData: !Base64
          Fn::Sub: |
            #!/bin/bash
            yum install -y aws-cfn-bootstrap
            /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${AWS::Region}
            /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}
  ELBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow access to the ELB
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - !If 
          - UseALBSSL
          - IpProtocol: tcp
            FromPort: 443
            ToPort: 443
            CidrIp: 0.0.0.0/0
          - IpProtocol: tcp
            FromPort: 80
            ToPort: 80
            CidrIp: 0.0.0.0/0
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Subnets: !Ref Subnets
      SecurityGroups:
        - !Ref ELBSecurityGroup
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ALBTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: !If
        - UseALBSSL
        - 443
        - 80
      Protocol: !If 
        - UseALBSSL
        - HTTPS
        - HTTP
      Certificates:
        - !If 
          - UseALBSSL
          - CertificateArn: !Ref ALBSSLCertificateARN
          - !Ref 'AWS::NoValue'
  ALBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 3
      Port: 80
      Protocol: HTTP
      UnhealthyThresholdCount: 5
      VpcId: !Ref VpcId
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access and HTTP access on the inbound port
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Select 
            - 0
            - !GetAtt 
              - ApplicationLoadBalancer
              - SecurityGroups
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
      VpcId: !Ref VpcId
  RecordSet:
    Type: AWS::Route53::RecordSetGroup
    Condition: UseALBSSL
    Properties:
      HostedZoneName: !Join 
        - ''
        - - !Ref HostedZoneName
          - .
      RecordSets:
        - Name: !Join 
            - ''
            - - !Select 
                - '0'
                - !Split 
                  - .
                  - !GetAtt 
                    - ApplicationLoadBalancer
                    - DNSName
              - .
              - !Ref HostedZoneName
              - .
          Type: A
          AliasTarget:
            DNSName: !GetAtt 
              - ApplicationLoadBalancer
              - DNSName
            EvaluateTargetHealth: true
            HostedZoneId: !GetAtt 
              - ApplicationLoadBalancer
              - CanonicalHostedZoneID
Outputs:
  URL:
    Description: URL of the website
    Value: !Join 
      - ''
      - - !If 
          - UseALBSSL
          - !Join 
            - ''
            - - 'https://'
              - !Join 
                - ''
                - - !Select 
                    - '0'
                    - !Split 
                      - .
                      - !GetAtt 
                        - ApplicationLoadBalancer
                        - DNSName
                  - .
                  - !Ref HostedZoneName
                  - .
          - !Join 
            - ''
            - - 'http://'
              - !GetAtt 
                - ApplicationLoadBalancer
                - DNSName
```

# CloudFormation 模板 Conditions 语法
<a name="conditions-section-structure"></a>

可选的 `Conditions` 部分包含一些声明，以定义在哪些情况下创建或配置实体。例如，您可以创建一个条件，然后将其与某个资源或输出关联，以便 CloudFormation 仅在该条件成立时创建该资源或输出。同样，您可以将条件与一个属性关联，以便 CloudFormation 仅在该条件为 true 时将该属性设置为特定的值。如果该条件为 false，则 CloudFormation 会将该属性设置为您指定的其他值。

当您需要重新使用模板在不同环境（如测试环境与生产环境）中创建资源时，可以使用条件。例如，在模板中，您可以添加 `EnvironmentType` 输入参数，它接受 `prod` 或 `test` 以作为输入。对于 `prod` 环境，您可以采用带特定功能的 EC2 实例；但对于 `test` 环境，您可以使用更少功能，以便节约资金。通过定义条件，您可以定义为每个环境类型创建哪些资源以及如何配置资源。

## 语法
<a name="conditions-section-structure-syntax"></a>

`Conditions` 部分包括键名称 `Conditions`。每个条件声明均包括一个逻辑 ID 和多个内置函数。

### JSON
<a name="conditions-section-structure-syntax.json"></a>

```
"Conditions": {
  "LogicalConditionName1": {
    "Intrinsic function": ...[
  },

  "LogicalConditionName2": {
    "Intrinsic function": ...
  }
}
```

### YAML
<a name="conditions-section-structure-syntax.yaml"></a>

```
Conditions:
  LogicalConditionName1:
    Intrinsic function:
      ...

  LogicalConditionName2:
    Intrinsic function:
      ...
```

## 条件的工作原理
<a name="conditions-section-structure-overview"></a>

要使用条件，请按照下列步骤操作：

1. **添加参数定义**：定义条件在模板 `Parameters` 部分中进行评估的输入。根据这些输入参数的值，条件评估结果为 true 或 false。请注意，伪参数是自动可用的，不需要在 `Parameters` 部分中进行明确定义。有关伪参数的更多信息，请参阅[使用伪参数获取 AWS 值](pseudo-parameter-reference.md)。

1. **添加条件定义**：使用内置函数（例如 `Fn::If` 或 `Fn::Equals`）在 `Conditions` 部分中定义条件。这些条件将决定 CloudFormation 何时创建关联的资源。条件可以基于：
   + 输入或伪参数值
   + 其他条件
   + 映射值

   但是，您不能在条件中引用资源逻辑 ID 或其属性。

1. **将条件与资源或输出关联**：使用 `Condition` 键和条件的逻辑 ID 在资源或输出中引用条件。或者，也可以在模板的其他部分（例如属性值）中使用 `Fn::If` 以根据条件设置值。有关更多信息，请参阅 [使用 `Condition` 密钥](#using-conditions-in-templates)。

在创建或更新堆栈时，CloudFormation 会评估条件。CloudFormation 创建与成立的条件关联的实体，并忽略与不成立的条件关联的实体。在每个堆栈更新期间，CloudFormation 还会在修改任何资源之前重新评估这些条件。与 true 条件关联的实体将会更新，与 false 条件关联的实体将会删除。

**重要**  
堆栈更新期间，您无法更新条件本身。您只能在包含添加、修改或删除资源的更改时更新条件。

## 条件内部函数
<a name="conditions-section-structure-functions"></a>

您可以使用以下内部函数定义条件：
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-foreach.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-foreach.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or)

**注意**  
仅在模板的 `Resources` 和 `Outputs` 部分中的元数据属性、更新策略属性和属性值中支持 `Fn::If`。

## 使用 `Condition` 密钥
<a name="using-conditions-in-templates"></a>

定义条件后，您可以使用 `Condition` 密钥将其应用于模板中的多个位置，例如 `Resources` 和 `Outputs`。`Condition` 密钥引用条件的逻辑名称并返回指定条件的评估结果。

**Topics**
+ [将条件与资源关联](#associate-conditions-with-resources)
+ [将条件与输出关联](#associate-conditions-with-outputs)
+ [其他条件中的引用条件](#reference-conditions-in-other-conditions)
+ [使用 `Fn::If` 有条件地返回属性值](#conditional-return-property-values-using-fn-if)

### 将条件与资源关联
<a name="associate-conditions-with-resources"></a>

要有条件地创建资源，请添加 `Condition` 密钥，并将条件的逻辑 ID 作为属性添加到该资源中。仅当 条件评估为 true 时，CloudFormation 才会创建 资源。

#### JSON
<a name="associate-conditions-with-resources.json"></a>

```
"NewVolume" : {
  "Type" : "AWS::EC2::Volume",
  "Condition" : "IsProduction",
  "Properties" : {
     "Size" : "100",
     "AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ]}
  }
}
```

#### YAML
<a name="associate-conditions-with-resources.yaml"></a>

```
NewVolume:
  Type: AWS::EC2::Volume
  Condition: IsProduction
  Properties:
    Size: 100
    AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
```

### 将条件与输出关联
<a name="associate-conditions-with-outputs"></a>

您还可以将条件与输出关联。仅当关联条件的评估结果为 true 时，CloudFormation 才会创建输出。

#### JSON
<a name="associate-conditions-with-outputs.json"></a>

```
"Outputs" : {
  "VolumeId" : {
    "Condition" : "IsProduction",
    "Value" : { "Ref" : "NewVolume" }
  }
}
```

#### YAML
<a name="associate-conditions-with-outputs.yaml"></a>

```
Outputs:
  VolumeId:
    Condition: IsProduction
    Value: !Ref NewVolume
```

### 其他条件中的引用条件
<a name="reference-conditions-in-other-conditions"></a>

在 `Conditions` 部分中定义条件时，可以使用 `Condition` 密钥引用其他条件。这使您能够通过组合多个条件来创建更复杂的条件逻辑。

在以下示例中，仅当 `IsProduction` 和 `IsProdAndFeatureEnabled` 条件的评估结果为 true 时，`IsFeatureEnabled` 条件才会评估为 true。

#### JSON
<a name="reference-conditions-in-other-conditions.json"></a>

```
"Conditions": {
  "IsProduction" : {"Fn::Equals" : [{"Ref" : "Environment"}, "prod"]},
  "IsFeatureEnabled" : { "Fn::Equals" : [{"Ref" : "FeatureFlag"}, "enabled"]},
  "IsProdAndFeatureEnabled" : {
    "Fn::And" : [
      {"Condition" : "IsProduction"},
      {"Condition" : "IsFeatureEnabled"}
    ]
  }
}
```

#### YAML
<a name="reference-conditions-in-other-conditions.yaml"></a>

```
Conditions:
  IsProduction:
    !Equals [!Ref Environment, "prod"]
  IsFeatureEnabled:
    !Equals [!Ref FeatureFlag, "enabled"]
  IsProdAndFeatureEnabled: !And
    - !Condition IsProduction
    - !Condition IsFeatureEnabled
```

### 使用 `Fn::If` 有条件地返回属性值
<a name="conditional-return-property-values-using-fn-if"></a>

要进行更精细的控制，您可以使用 `Fn::If` 内置函数有条件地返回资源或输出中的两个属性值之一。该函数会对条件进行评估，如果条件为 true，则返回一个值；如果条件为 false，则返回另一个值。

#### 条件属性值
<a name="using-fn-if-for-conditional-values"></a>

以下示例演示了如何根据环境条件设置 EC2 实例类型。如果 `IsProduction` 条件的评估结果为 true，则实例类型设置为 `c5.xlarge`。否则，该值将设置为 `t3.small`。

##### JSON
<a name="using-fn-if-for-conditional-values.json"></a>

```
"Properties" : {
  "InstanceType" : {
    "Fn::If" : [
      "IsProduction",
      "c5.xlarge",
      "t3.small"
    ]
  }
}
```

##### YAML
<a name="using-fn-if-for-conditional-values.yaml"></a>

```
Properties:
  InstanceType: !If
    - IsProduction
    - c5.xlarge
    - t3.small
```

#### 条件属性移除
<a name="using-fn-if-with-novalue"></a>

您也可以使用 `AWS::NoValue` 伪参数名称】作为返回值，在条件为 false 时移除对应的属性。

##### JSON
<a name="using-fn-if-with-novalue.json"></a>

```
"DBSnapshotIdentifier" : {
  "Fn::If" : [
    "UseDBSnapshot",
    {"Ref" : "DBSnapshotName"},
    {"Ref" : "AWS::NoValue"}
  ]
}
```

##### YAML
<a name="using-fn-if-with-novalue.yaml"></a>

```
DBSnapshotIdentifier: !If
  - UseDBSnapshot
  - !Ref DBSnapshotName
  - !Ref "AWS::NoValue"
```

## 示例
<a name="conditions-section-structure-examples"></a>

**Topics**
+ [基于环境创建资源](#environment-based-resource-creation)
+ [多条件资源预置](#multi-condition-resource-provisioning)

### 基于环境创建资源
<a name="environment-based-resource-creation"></a>

以下示例将预置一个 EC2 实例，并且仅当环境类型为 `prod` 时，才会有条件地创建和附加新的 EBS 卷。如果环境是 `test`，示例则只会创建不带额外卷的 EC2 实例。

#### JSON
<a name="conditions-section-example-resource-creation.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "EnvType": {
            "Description": "Environment type",
            "Default": "test",
            "Type": "String",
            "AllowedValues": [
                "prod",
                "test"
            ],
            "ConstraintDescription": "must specify prod or test"
        }
    },
    "Conditions": {
        "IsProduction": {
            "Fn::Equals": [
                {
                    "Ref": "EnvType"
                },
                "prod"
            ]
        }
    },
    "Resources": {
        "EC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": "ami-1234567890abcdef0",
                "InstanceType": "c5.xlarge"
            }
        },
        "MountPoint": {
            "Type": "AWS::EC2::VolumeAttachment",
            "Condition": "IsProduction",
            "Properties": {
                "InstanceId": {
                    "Ref": "EC2Instance"
                },
                "VolumeId": {
                    "Ref": "NewVolume"
                },
                "Device": "/dev/sdh"
            }
        },
        "NewVolume": {
            "Type": "AWS::EC2::Volume",
            "Condition": "IsProduction",
            "Properties": {
                "Size": 100,
                "AvailabilityZone": {
                    "Fn::GetAtt": [
                        "EC2Instance",
                        "AvailabilityZone"
                    ]
                }
            }
        }
    }
}
```

#### YAML
<a name="conditions-section-example-resource-creation.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EnvType:
    Description: Environment type
    Default: test
    Type: String
    AllowedValues:
      - prod
      - test
    ConstraintDescription: must specify prod or test
Conditions:
  IsProduction: !Equals
    - !Ref EnvType
    - prod
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-1234567890abcdef0
      InstanceType: c5.xlarge
  MountPoint:
    Type: AWS::EC2::VolumeAttachment
    Condition: IsProduction
    Properties:
      InstanceId: !Ref EC2Instance
      VolumeId: !Ref NewVolume
      Device: /dev/sdh
  NewVolume:
    Type: AWS::EC2::Volume
    Condition: IsProduction
    Properties:
      Size: 100
      AvailabilityZone: !GetAtt
        - EC2Instance
        - AvailabilityZone
```

### 多条件资源预置
<a name="multi-condition-resource-provisioning"></a>

如果提供了存储桶名称，则以下示例会有条件地创建 S3 存储桶，并且仅当环境设置为 `prod` 时，才会附加存储桶策略。如果未提供存储桶名称或环境为 `test`，则不会创建任何资源。

#### JSON
<a name="conditions-section-example-multi-condition.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "EnvType": {
            "Type": "String",
            "AllowedValues": [
                "prod",
                "test"
            ]
        },
        "BucketName": {
            "Default": "",
            "Type": "String"
        }
    },
    "Conditions": {
        "IsProduction": {
            "Fn::Equals": [
                {
                    "Ref": "EnvType"
                },
                "prod"
            ]
        },
        "CreateBucket": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "BucketName"
                        },
                        ""
                    ]
                }
            ]
        },
        "CreateBucketPolicy": {
            "Fn::And": [
                {
                    "Condition": "IsProduction"
                },
                {
                    "Condition": "CreateBucket"
                }
            ]
        }
    },
    "Resources": {
        "Bucket": {
            "Type": "AWS::S3::Bucket",
            "Condition": "CreateBucket",
            "Properties": {
                "BucketName": {
                    "Ref": "BucketName"
                }
            }
        },
        "Policy": {
            "Type": "AWS::S3::BucketPolicy",
            "Condition": "CreateBucketPolicy",
            "Properties": {
                "Bucket": {
                    "Ref": "Bucket"
                },
                "PolicyDocument": { ... }
            }
        }
    }
}
```

#### YAML
<a name="conditions-section-example-multi-condition.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EnvType:
    Type: String
    AllowedValues:
      - prod
      - test
  BucketName:
    Default: ''
    Type: String
Conditions:
  IsProduction: !Equals
    - !Ref EnvType
    - prod
  CreateBucket: !Not
    - !Equals
      - !Ref BucketName
      - ''
  CreateBucketPolicy: !And
    - !Condition IsProduction
    - !Condition CreateBucket
Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Condition: CreateBucket
    Properties:
      BucketName: !Ref BucketName
  Policy:
    Type: AWS::S3::BucketPolicy
    Condition: CreateBucketPolicy
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument: ...
```

在此示例中，`CreateBucketPolicy` 条件演示了如何使用 `Condition` 密钥引用其他条件。只有当 `IsProduction` 和 `CreateBucket` 条件的评估结果都为 true 时，才会创建策略。

**注意**  
有关使用条件的更复杂的示例，请参阅《*CloudFormation模板参考指南*》中的[Condition 属性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-condition.html)主题。

# CloudFormation 模板 Transform 部分
<a name="transform-section-structure"></a>

可选的 `Transform` 部分指定 CloudFormation 用来以某种方式处理模板的一个或多个宏。

宏可以执行查找和替换文本等简单任务，也可以对整个模板进行更广泛的转换。CloudFormation 按照指定的顺序执行宏。当您创建更改集时，CloudFormation 会生成一个包含已处理模板内容的更改集。然后，您可以查看更改并执行更改集。有关宏工作原理的更多信息，请参阅[使用模板宏对 CloudFormation 模板执行自定义处理](template-macros.md)。

CloudFormation 还支持*转换*，后者是由 CloudFormation 托管的宏。在执行顺序和范围方面，CloudFormation 以相同的方法处理转换以及您创建的任何宏。有关更多信息，请参阅[转换参考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-reference.html)。

要声明多个宏，请使用列表格式并指定一个或多个宏。

例如，在下面的模板示例中，CloudFormation 会首先评估 `MyMacro`，然后再评估 `AWS::Serverless`，并且两者都可以处理整个模板的内容，因为它们包含在 `Transform` 部分中。

```
# Start of processable content for MyMacro and AWS::Serverless
Transform:
  - MyMacro
  - 'AWS::Serverless'
Resources:
  WaitCondition:
    Type: AWS::CloudFormation::WaitCondition
  MyBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: amzn-s3-demo-bucket
      Tags: [{"key":"value"}]
      CorsConfiguration: []
  MyEc2Instance:
    Type: AWS::EC2::Instance 
    Properties:
      ImageId: ami-1234567890abcdef0
# End of processable content for MyMacro and AWS::Serverless
```

# CloudFormation 模板格式版本语法
<a name="format-version-structure"></a>

`AWSTemplateFormatVersion` 部分（可选）用于标识模板要符合的模板格式版本。最新的模板格式版本是 `2010-09-09`，并且它是目前唯一的有效值。

模板格式版本与 API 版本不同。模板格式版本可独立于 API 版本进行更改。

模板格式版本声明的值必须是文字字符串。您无法使用参数或函数来指定模板格式版本。如果您没有指定任何值，则 CloudFormation 会假定为最新的模板格式版本。以下代码段是有效的模板格式版本声明的示例：

## JSON
<a name="format-version-structure-example.json"></a>

```
"AWSTemplateFormatVersion" : "2010-09-09"
```

## YAML
<a name="format-version-structure-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
```

# CloudFormation 模板 Description 语法
<a name="template-description-structure"></a>

`Description` 部分（可选）可用来包含描述模板的文本字符串。此部分必须始终紧随模板格式版本部分之后。

描述声明的值必须是长度介于 0 和 1024 个字节之间的文字字符串。您无法使用参数或函数来指定描述。以下代码段是描述声明的示例：

**重要**  
堆栈更新期间，您无法更新 `Description` 部分本身。您只能在包括添加、修改或删除资源的更改时更新它。

## JSON
<a name="template-description-structure-example.json"></a>

```
"Description" : "Here are some details about the template."
```

## YAML
<a name="template-description-structure-example.yaml"></a>

```
Description: > Here are some details about the template.
```