

# 使用 CloudFormation 提供的参数类型在运行时指定现有资源
<a name="cloudformation-supplied-parameter-types"></a>

创建模板时，您可以使用 CloudFormation 提供的专用参数类型创建要求用户输入现有 AWS 资源标识符或 Systems Manager 参数的参数。

**Topics**
+ [概述](#cloudformation-supplied-parameter-types-overview)
+ [示例](#cloudformation-supplied-parameter-types-example)
+ [注意事项](#cloudformation-supplied-parameter-types-considerations)
+ [支持的特定于 AWS 的参数类型](#aws-specific-parameter-types-supported)
+ [支持的 Systems Manager 参数类型](#systems-manager-parameter-types-supported)
+ [不支持的 Systems Manager 参数类型](#systems-manager-parameter-types-unsupported)

## 概述
<a name="cloudformation-supplied-parameter-types-overview"></a>

在 CloudFormation 中，您可以通过在堆栈创建或更新期间提供输入值，从而使用参数来自定义堆栈。此功能使您的模板可以在不同的场景中重复使用并提高灵活性。

参数是在 CloudFormation 模板的 `Parameters` 部分中定义的。每个参数都有一个名称和一个类型，此外还可以配置其他设置，例如默认值和允许值。有关更多信息，请参阅 [CloudFormation 模板 Parameters 语法](parameters-section-structure.md)。

参数类型决定了参数可以接受的输入值种类。例如，`Number` 只接受数值，而 `String` 可接受文本输入。

CloudFormation 提供了几种额外的参数类型，您可以在模板中使用这些参数类型来引用现有 AWS 资源和 Systems Manager 参数。

这些参数类型分为两类：
+ **AWS 特定参数类型**：CloudFormation 提供了一组参数类型，可帮助在创建或更新堆栈时捕获无效值。当您使用这些参数类型时，使用您模板的任何人都必须指定其创建堆栈的 AWS 账户和区域中的有效值。

  如果他们使用 AWS 管理控制台，则 CloudFormation 会预先填充其账户和区域现有值的列表。这样一来，用户便无需记住和正确键入特定的名称或 ID，相反，他们只需从下拉列表中选择值。在某些情况下，他们甚至还可以按 ID、名称或 `Name` 标签值来搜索值。
+ **Systems Manager 参数类型**：CloudFormation 还提供与 Systems Manager Parameter Store 中现有参数相对应的参数类型。当您使用这些参数类型时，使用您的模板的任何人都必须指定 Parameter Store 键作为 Systems Manager 参数类型的值，然后 CloudFormation 从 Parameter Store 中检索最新值以在其堆栈中使用。当您需要使用新亚马逊机器映像（AMI）ID 等新属性值来频繁更新应用程序时，这可能非常实用。有关 Parameter Store 的更多信息，请参阅 [Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)。

在 `Parameters` 部分中定义参数后，您可以使用 `Ref` 函数在整个 CloudFormation 模板中引用这些参数值。

## 示例
<a name="cloudformation-supplied-parameter-types-example"></a>

以下示例展示一个使用以下参数类型的模板。
+ `AWS::EC2::VPC::Id`
+ `AWS::EC2::Subnet::Id`
+ `AWS::EC2::KeyPair::KeyName`
+ `AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>`

要通过此模板创建堆栈，您必须指定账户中的现有 VPC ID、子网 ID 和密钥对名称。您也可以指定引用所需 AMI ID 的现有 Parameter Store 键或保留 `/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2` 的默认值。此公有参数是最新 Amazon Linux 2 AMI 的区域 AMI ID 的别名。有关公有参数的更多信息，请参阅《AWS Systems Manager 用户指南》**中的[发现 Parameter Store 中的公有参数](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)。

### JSON
<a name="cloudformation-supplied-parameter-types-example.json"></a>

```
{
    "Parameters": {
        "VpcId": {
            "Description": "ID of an existing Virtual Private Cloud (VPC).",
            "Type": "AWS::EC2::VPC::Id"
        },
        "PublicSubnetId": {
            "Description": "ID of an existing public subnet within the specified VPC.",
            "Type": "AWS::EC2::Subnet::Id"
        },
        "KeyName": {
            "Description": "Name of an existing EC2 key pair to enable SSH access to the instance.",
            "Type": "AWS::EC2::KeyPair::KeyName"
        },
        "AMIId": {
            "Description": "Name of a Parameter Store parameter that stores the ID of the Amazon Machine Image (AMI).",
            "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
            "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
        }
    },
    "Resources": {
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "VpcId": { "Ref": "VpcId" },
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        },
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "KeyName": { "Ref": "KeyName" },
                "ImageId": { "Ref": "AMIId" },
                "NetworkInterfaces": [
                    {
                        "AssociatePublicIpAddress": "true",
                        "DeviceIndex": "0",
                        "SubnetId": { "Ref": "PublicSubnetId" },
                        "GroupSet": [{ "Ref": "InstanceSecurityGroup" }]
                    }
                ]
            }
        }
    },
    "Outputs": {
        "InstanceId": {
            "Value": { "Ref": "Ec2Instance" }
        }
    }
}
```

### YAML
<a name="cloudformation-supplied-parameter-types-example.yaml"></a>

```
Parameters:
  VpcId:
    Description: ID of an existing Virtual Private Cloud (VPC).
    Type: AWS::EC2::VPC::Id
  PublicSubnetId:
    Description: ID of an existing public subnet within the specified VPC.
    Type: AWS::EC2::Subnet::Id
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance.
    Type: AWS::EC2::KeyPair::KeyName
  AMIId:
    Description: Name of a Parameter Store parameter that stores the ID of the Amazon Machine Image (AMI).
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      KeyName: !Ref KeyName
      ImageId: !Ref AMIId
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PublicSubnetId
          GroupSet:
            - !Ref InstanceSecurityGroup
Outputs:
  InstanceId:
    Value: !Ref Ec2Instance
```

### 用于创建堆栈的 AWS CLI 命令
<a name="cloudformation-supplied-parameter-types-cli-command"></a>

以下 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html) 命令基于示例模板创建堆栈。

```
aws cloudformation create-stack --stack-name MyStack \
  --template-body file://sampletemplate.json \
  --parameters \
ParameterKey="VpcId",ParameterValue="vpc-a123baa3" \
ParameterKey="PublicSubnetId",ParameterValue="subnet-123a351e" \
ParameterKey="KeyName",ParameterValue="MyKeyName" \
ParameterKey="AMIId",ParameterValue="MyParameterKey"
```

要使用接受字符串列表的参数类型（例如 `List<AWS::EC2::Subnet::Id>`），必须使用双反斜杠对 `ParameterValue` 中的逗号进行转义，如以下示例所示。

```
--parameters ParameterKey="SubnetIDs",ParameterValue="subnet-5ea0c127\\,subnet-6194ea3b\\,subnet-c87f2be0"
```

## 注意事项
<a name="cloudformation-supplied-parameter-types-considerations"></a>

强烈建议使用动态引用来限制对敏感配置定义（例如第三方凭证）的访问。有关更多信息，请参阅 [使用动态引用获取存储在其他服务中的值](dynamic-references.md)。

如果要允许模板用户指定不同 AWS 账户的值，则请不要使用 AWS 特定参数类型。而是应定义 `String` 或 `CommaDelimitedList` 类型的参数。

对于 Systems Manager 参数类型，需要注意以下几点：
+ 您可以在控制台中或通过运行 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) 或 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-change-set.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-change-set.html) 来查看堆栈的**参数**选项卡上的已解析参数值。请记住，这些值是在创建或更新堆栈时设置的，因此它们可能与 Parameter Store 中的最新值不同。
+ 对于堆栈更新，当您使用**使用现有值**选项（或将 `UsePreviousValue` 设置为 true）时，这意味着您要继续使用相同的 Parameter Store 键，而不是其值。CloudFormation 始终检索最新值。
+ 如果您指定了任何允许的值或其他约束，则 CloudFormation 会根据您指定的参数键对其进行验证，但不会验证其值。您应该在 Parameter Store 本身中验证这些值。
+ 创建或更新堆栈并创建更改集时，CloudFormation 会使用当时 Parameter Store 中存在的任何值。如果某个指定的参数在调用方的 AWS 账户下的 Parameter Store 中不存在，CloudFormation 会返回验证错误。
+ 执行更改集时，CloudFormation 将使用在更改集中指定的值。您应在执行更改集前检查这些值，因为在您创建更改集和运行更改集之间的时间内，它们可能会在 Parameter Store 中发生更改。
+ 对于存储在同一 AWS 账户中的 Parameter Store 参数，必须提供参数名称。对于由其他 AWS 账户共享的 Parameter Store 参数，必须提供完整的参数 ARN。

## 支持的特定于 AWS 的参数类型
<a name="aws-specific-parameter-types-supported"></a>

CloudFormation 支持以下 AWS 特定的类型：

`AWS::EC2::AvailabilityZone::Name`  
可用区，如 `us-west-2a`。

`AWS::EC2::Image::Id`  
Amazon EC2 映像 ID，如 `ami-0ff8a91507f77f867`。请注意，CloudFormation 控制台不会显示此参数类型的值的下拉列表。

`AWS::EC2::Instance::Id`  
Amazon EC2 实例 ID，如 `i-1e731a32`。

`AWS::EC2::KeyPair::KeyName`  
Amazon EC2 密钥对名称。

`AWS::EC2::SecurityGroup::GroupName`  
默认 VPC 安全组名称，例如 `my-sg-abc`。

`AWS::EC2::SecurityGroup::Id`  
安全组 ID，如 `sg-a123fd85`。

`AWS::EC2::Subnet::Id`  
子网 ID，如 `subnet-123a351e`。

`AWS::EC2::Volume::Id`  
Amazon EBS 卷 ID，如 `vol-3cdd3f56`。

`AWS::EC2::VPC::Id`  
VPC ID，如 `vpc-a123baa3`。

`AWS::Route53::HostedZone::Id`  
Amazon Route 53 托管区域 ID，如 `Z23YXV4OVPL04A`。

`List<AWS::EC2::AvailabilityZone::Name>`  
针对某个区域的一组可用区，如 `us-west-2a, us-west-2b`。

`List<AWS::EC2::Image::Id>`  
一组 Amazon EC2 映像 ID，如 `ami-0ff8a91507f77f867, ami-0a584ac55a7631c0c`。请注意，CloudFormation 控制台不会显示此参数类型的值的下拉列表。

`List<AWS::EC2::Instance::Id>`  
一组 Amazon EC2 实例 ID，如 `i-1e731a32, i-1e731a34`。

`List<AWS::EC2::SecurityGroup::GroupName>`  
一组默认 VPC 安全组名称，例如 `my-sg-abc, my-sg-def`。

`List<AWS::EC2::SecurityGroup::Id>`  
一组安全组 ID，如 `sg-a123fd85, sg-b456fd85`。

`List<AWS::EC2::Subnet::Id>`  
一组子网 ID，如 `subnet-123a351e, subnet-456b351e`。

`List<AWS::EC2::Volume::Id>`  
一组 Amazon EBS 卷 ID，如 `vol-3cdd3f56, vol-4cdd3f56`。

`List<AWS::EC2::VPC::Id>`  
一组 VPC ID，如 `vpc-a123baa3, vpc-b456baa3`。

`List<AWS::Route53::HostedZone::Id>`  
一组 Amazon Route 53 托管区域 ID，如 `Z23YXV4OVPL04A, Z23YXV4OVPL04B`。

## 支持的 Systems Manager 参数类型
<a name="systems-manager-parameter-types-supported"></a>

CloudFormation 支持以下 Systems Manager 参数类型：

`AWS::SSM::Parameter::Name`  
Systems Manager 参数键的名称。仅使用此参数类型来检查所需的参数是否存在。CloudFormation 不会检索与该参数关联的实际值。

`AWS::SSM::Parameter::Value<String>`  
其值是字符串的 Systems Manager 参数。这与 Parameter Store 中的 `String` 参数对应。

`AWS::SSM::Parameter::Value<List<String>>` 或 `AWS::SSM::Parameter::Value<CommaDelimitedList>`  
其值是字符串列表的 Systems Manager 参数。这与 Parameter Store 中的 `StringList` 参数对应。

`AWS::SSM::Parameter::Value<AWS-specific parameter type>`  
其值是 AWS 特定参数类型的 Systems Manager 参数。  
例如，下面指定了 `AWS::EC2::KeyPair::KeyName` 类型：  
+ `AWS::SSM::Parameter::Value<AWS::EC2::KeyPair::KeyName>`

`AWS::SSM::Parameter::Value<List<AWS-specific parameter type>>`  
其值是 AWS 特定参数类型列表的 Systems Manager 参数。  
例如，下面指定了 `AWS::EC2::KeyPair::KeyName` 类型的列表：  
+ `AWS::SSM::Parameter::Value<List<AWS::EC2::KeyPair::KeyName>>`

## 不支持的 Systems Manager 参数类型
<a name="systems-manager-parameter-types-unsupported"></a>

CloudFormation 不支持以下 Systems Manager 参数类型：
+ Systems Manager 参数类型的列表，例如：`List<AWS::SSM::Parameter::Value<String>>`

此外，CloudFormation 不支持将模板参数定义为 `SecureString` Systems Manager 参数类型。不过对于某些资源，您可以将安全字符串指定为参数*值*。有关更多信息，请参阅 [使用动态引用获取存储在其他服务中的值](dynamic-references.md)。