使用动态引用以指定模板值 - AWS CloudFormation
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

使用动态引用以指定模板值

动态引用提供了一种简洁、强大的方法,用于指定在堆栈模板内的其他服务中存储和管理的外部值,例如堆栈模板中的 Systems Manager Parameter Store。当您使用动态引用时,CloudFormation 会在堆栈和更改集合操作期间在必要时检索指定引用的值。

CloudFormation 目前支持以下动态引用模式:

  • ssm(对于在 AWS Systems Manager Parameter Store 中存储的纯文本值)

  • ssm-secure(对于在 AWS Systems Manager Parameter Store 中存储的安全字符串)

  • secretsmanager(对于在 AWS Secrets Manager 存储中的整个密钥或特定密钥值)

使用动态引用时的一些注意事项:

  • 您最多可以在堆栈模板中包含 60 个动态引用。

  • 对于转换,例如 AWS::Include 和 AWS::Serverless,AWS CloudFormation 在调用任何转换之前不解析动态引用。相反,AWS CloudFormation 会将动态引用的文本字符串传递给转换。当使用模板执行更改集时,将会解析动态引用(包括那些作为转换结果插入到已处理模板中的引用)。

  • 自定义资源中目前不支持安全值的动态引用,例如 ssm-securesecretsmanager

注意

请不要创建将反斜杠 (\) 用作最终值的动态参考。AWS CloudFormation 无法解析这些参考,而导致资源失败。

在堆栈模板中指定动态引用

动态引用遵循以下模式:

'{{resolve:service-name:reference-key}}'

service-name

指定要在其中存储和管理值的服务。

必填项。

目前,有效值包括:

  • ssm:Systems Manager Parameter Store 纯文本参数。

  • ssm-secure:Systems Manager Parameter Store 安全字符串参数。

    注意

    目前,cn-north-1cn-northwest-1 区域中的 Systems Manager 不支持 SecureString 参数。

    有关更多信息,请参阅 AWS Systems Manager 用户指南 中的 AWS Systems Manager Parameter Store

  • secretsmanager:AWS Secrets Manager 密钥。

reference-key

引用键。根据动态引用的类型,引用键可以包括多个分段。

必需。

SSM 参数

使用 ssm 动态引用,将在类型为 StringStringList 的 Systems Manager Parameter Store 中存储的值包含在模板中。

引用模式

对于 SSM 参数,reference-key 分段由参数名称和版本号组成。请使用以下模式:

'{{resolve:ssm:parameter-name:version}}'

您的引用必须遵循以下参数名称和版本的正则表达式模式:

'{{resolve:ssm:[a-zA-Z0-9_.-/]+:\\d+}}'

parameter-name

Systems Manager Parameter Store 中的参数的名称。参数名称区分大小写。

必需。

version

一个整数,指定要使用的参数的版本。您必须指定确切的版本。目前,您无法指定 AWS CloudFormation 使用参数的最新版本。有关更多信息,请参阅 AWS Systems Manager 用户指南 中的使用参数版本

必需。

示例

以下示例使用 ssm 动态引用将 S3 存储桶的访问控制设置为在 Systems Manager Parameter Store 中存储的参数值。如指定的那样,CloudFormation 将使用 S3AccessControl 参数的版本 2 进行堆栈和更改集操作。

JSON

"MyS3Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "AccessControl": "{{resolve:ssm:S3AccessControl:2}}" } }

YAML

  MyS3Bucket:     Type: 'AWS::S3::Bucket'     Properties:       AccessControl: '{{resolve:ssm:S3AccessControl:2}}'

要指定一个存储在 Systems Manager Parameter Store 中的参数,您必须有权为指定的参数调用 GetParameters。有关更多信息,请参阅AWS Systems Manager 用户指南中的控制对 Systems Manager 参数的访问权限

使用 ssm 动态引用模式时需要注意的其他注意事项:

  • 目前,CloudFormation 不支持跨账户 SSM 参数访问。

  • 对于自定义资源,CloudFormation 在将请求发送到自定义资源之前解析 ssm 动态引用。有关更多信息,请参阅 自定义资源

  • CloudFormation 不支持在动态引用中使用参数标签或公有参数。

    参数标签是用户定义的别名,帮助管理参数的不同版本。有关更多信息,请参阅AWS Systems Manager 用户指南中的标记参数

    公有参数是 AWS 服务提供的用于与该服务一起使用的参数,存储在 AWS Systems Manager Parameter Store 中。有关公有参数的示例,请参阅Amazon Elastic Container Service Developer Guide中的检索 Amazon ECS 优化的 AMI 元数据

SSM 安全字符串参数

使用 ssm-secure 动态引用模式在模板中指定 AWS Systems Manager SecureString 类型参数。对于 ssm-secure 动态引用,AWS CloudFormation 绝不会存储实际参数值。AWS CloudFormation 在堆栈和更改集的创建和更新操作期间访问参数值。目前,只能将安全字符串参数用于支持 ssm-secure 动态引用模式的资源属性

安全字符串参数是需要以安全的方式存储和引用的任何敏感数据。也就是说,您不希望用户以明文形式更改或引用的数据,例如密码或许可证密钥。有关安全字符串的更多信息,请参阅 AWS Systems Manager 用户指南 中的使用安全字符串参数

安全字符串参数值不存储在 CloudFormation 中,也不会在任何 API 调用结果中返回。

引用模式

对于 ssm-secure 动态引用,reference-key 分段由参数名称和版本号组成。请使用以下模式:

'{{resolve:ssm-secure:parameter-name:version}}'

您的引用必须遵循以下参数名称和版本的正则表达式模式:

'{{resolve:ssm-secure:[a-zA-Z0-9_.-/]+:\\d+}}'

parameter-name

Systems Manager Parameter Store 中的参数的名称。参数名称区分大小写。

必需。

version

一个整数,指定要使用的参数的版本。您必须指定确切的版本。目前,您无法指定 AWS CloudFormation 使用参数的最新版本。有关更多信息,请参阅 AWS Systems Manager 用户指南 中的使用参数版本

必需。

示例

以下示例使用 ssm-secure 动态引用将 IAM 用户的密码设置为在 Systems Manager Parameter Store 中存储的安全字符串。如指定的那样,CloudFormation 将使用 IAMUserPassword 参数的版本 10 进行堆栈和更改集操作。

JSON

"MyIAMUser": { "Type": "AWS::IAM::User", "Properties": { "UserName": "MyUserName", "LoginProfile": { "Password": "{{resolve:ssm-secure:IAMUserPassword:10}}" } } }

YAML

  MyIAMUser:     Type: AWS::IAM::User     Properties:       UserName: 'MyUserName'       LoginProfile:         Password: '{{resolve:ssm-secure:IAMUserPassword:10}}'

使用 ssm-secure 动态引用模式时需要注意的其他注意事项:

  • CloudFormation 不会在任何 API 调用中返回安全字符串的实际参数值,而是返回文本动态引用。

  • CloudFormation 不存储其中包含安全字符串的纯文本参数名称的文本动态引用。

  • 对于更改集,CloudFormation 会比较文本动态引用字符串。它不会解析并比较 ssm-secure 引用的实际值。

  • 自定义资源中目前不支持安全值的动态引用,例如 ssm-securesecretsmanager

  • 如果 CloudFormation 必须回滚堆栈更新,则如果先前指定的安全字符串参数版本不再可用,则该更新回滚操作将失败。在这种情况下,请执行以下操作之一:

    • 使用 CONTINUE_UPDATE_ROLLBACK 跳过资源。

    • 在 Systems Manager Parameter Store 中重新创建安全字符串参数,并更新它,直到参数版本达到模板中使用的版本。然后使用 CONTINUE_UPDATE_ROLLBACK 而无需跳过资源。

  • 目前,AWS CloudFormation 不支持跨账户 SSM 参数访问。

  • CloudFormation 不支持在动态引用中使用参数标签或公有参数。

    参数标签是用户定义的别名,帮助管理参数的不同版本。有关更多信息,请参阅AWS Systems Manager 用户指南中的标记参数

    公有参数是 AWS 服务提供的用于与该服务一起使用的参数,存储在 AWS Systems Manager Parameter Store 中。有关公有参数的示例,请参阅Amazon Elastic Container Service Developer Guide中的检索 Amazon ECS 优化的 AMI 元数据

对安全字符串支持动态参数模式的资源

支持 ssm-secure 动态引用模式的资源目前包括:

Secrets Manager 密钥

使用 secretsmanager 动态引用可检索在 AWS Secrets Manager 中存储的全部密钥或密钥值,以便在模板中使用。密钥可以是数据库凭证、密码、第三方 API 密钥,甚至是任意文本。使用 Secrets Manager,您可以集中存储和控制对这些密钥的访问权限。Secrets Manager 允许您将代码中的硬编码凭证(包括密码)替换为对 Secrets Manager 的 API 调用,以便以编程方式检索密钥。有关更多信息,请参阅 AWS Secrets Manager 用户指南 中的什么是 AWS Secrets Manager?

使用 Secrets Manager 密钥的动态参数时的重要注意事项

在堆栈模板中使用动态参数指定 Secrets Manager 密钥时,应考虑以下重要的安全注意事项:

  • secretsmanager 动态引用可用于所有资源属性。使用 secretsmanager 动态引用可保证 Secrets Manager 和 CloudFormation 都不记录或保留任何已解析的密钥值。但是,密钥值可能会显示在正在其资源中使用密钥值的服务中。您应该检查您的使用情况,以避免泄露密钥数据。

  • 在 Secrets Manager 中更新密钥不会自动更新 CloudFormation 中的密钥。为了让 CloudFormation 更新 secretsmanager 动态引用,您必须通过更新包含 secretsmanager 动态引用的资源属性或更新资源的另一个属性来执行堆栈更新,从而更新包含动态引用的资源。

    例如,假设您在模板中将 AWS::RDS::DBInstance 资源的 MasterPassword 属性指定为 secretsmanager 动态引用,然后基于该模板创建堆栈。您稍后在 Secret Manager 中更新该密钥的值,但不更新模板中的 AWS::RDS::DBInstance 资源。在这种情况下,即使您执行堆栈更新,MasterPassword 属性中的密钥值也不会更新,并保持之前的密钥值。

    要管理模板中的密钥更新,请考虑使用 version-id 来指定密钥的版本。然后,当您更新到下一个版本时,请在模板中更新 version-id 并执行堆栈更新。例如,如果指定以下分段,将会检索版本 ID 为 EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE 的 MySecret 密钥版本的 password 值。

      '{{resolve:secretsmanager:MySecret:SecretString:password:EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE}}'

    然后,当您更新 password 值时,您需要使用新的 version-id 更新此分段并执行堆栈更新。有关使用版本 ID 的更多示例,请参阅示例

    此外,请考虑使用 Secrets Manager 自动轮换受保护服务或数据库的密钥。有关更多信息,请参阅轮换您的 AWS Secrets Manager 密钥

  • 自定义资源中目前不支持安全值的动态引用,例如 secretsmanager

所需权限

要指定一个存储在 Secrets Manager Parameter Store 中的密钥,您必须有权为指定的密钥调用 GetSecretValue

引用模式

对于 Secrets Manager 密钥,reference-key 分段由多个分段组成,包括密钥 id、密钥值键、版本阶段和版本 id。请使用以下模式:

{{resolve:secretsmanager:secret-id:secret-string:json-key:version-stage:version-id}}

secret-id

用作密钥的唯一标识符的名称或 Amazon资源名称 (ARN)。

要访问您的 AWS 账户中的密钥,您只需指定密钥名称。要访问其他 AWS 账户中的密钥,请指定密钥的完整 ARN。

必需。

secret-string

目前,唯一支持的值是 SecretString。默认为 SecretString

json-key

指定要检索其值的键值对的键名称。如果您不指定 json-key,CloudFormation 会索整个密钥文本。

此分段不得包含冒号字符 ( : )。

version-stage

指定要按附加到版本的暂存标签检索的密钥版本。暂存标签用于在轮换过程中跟踪不同版本。如果您使用 version-stage,则不要指定 version-id。如果您不指定版本阶段或版本 ID,则默认设置是检索版本阶段值为 AWSCURRENT 的版本。

此分段不得包含冒号字符 ( : )。

version-id

指定要在堆栈操作中使用的密钥版本的唯一标识符。如果指定 version-id,则不要指定 version-stage。如果您不指定版本阶段或版本 ID,则默认设置是检索版本阶段值为 AWSCURRENT 的版本。

此分段不得包含冒号字符 ( : )。

示例

以下示例使用 secret-namejson-key 分段来检索在 MyRDSSecret 密钥中存储的用户名和密码值。默认情况下,检索的密钥版本是版本阶段值为 AWSCURRENT 的版本。

JSON

{ "MyRDSInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "DBName": "MyRDSInstance", "AllocatedStorage": "20", "DBInstanceClass": "db.t2.micro", "Engine": "mysql", "MasterUsername": "{{resolve:secretsmanager:MyRDSSecret:SecretString:username}}", "MasterUserPassword": "{{resolve:secretsmanager:MyRDSSecret:SecretString:password}}" } } }

YAML

MyRDSInstance: Type: 'AWS::RDS::DBInstance' Properties: DBName: MyRDSInstance AllocatedStorage: '20' DBInstanceClass: db.t2.micro Engine: mysql MasterUsername: '{{resolve:secretsmanager:MyRDSSecret:SecretString:username}}' MasterUserPassword: '{{resolve:secretsmanager:MyRDSSecret:SecretString:password}}'

如果指定以下分段,将会检索版本阶段值为 AWSCURRENT 的 MySecret 密钥版本的整个 SecretString 字段。

  '{{resolve:secretsmanager:MySecret}}' or '{{resolve:secretsmanager:MySecret::::}}'

如果指定以下分段,将会检索版本阶段值为 AWSCURRENT 的 MySecret SecretString 版本的 password 值。

  '{{resolve:secretsmanager:MySecret:SecretString:password}}'

如果指定以下分段,将会检索版本 ID 为 EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE 的 MySecret 密钥版本的 password 值。

  '{{resolve:secretsmanager:MySecret:SecretString:password:SecretString:EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE}}'

如果指定以下分段,将会从另一个 AWS 账户中检索版本阶段值为 AWSCURRENT 的 MySecret 密钥版本的整个 SecretString。请注意,您必须指定完整的密钥 ARN 才能访问另一个 AWS 账户中的密钥。

  '{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecret-asd123}}'

如果指定以下分段,将会从另一个 AWS 账户中检索版本阶段值为 AWSCURRENT 的 MySecret 密钥版本的 password 值。请注意,您必须指定完整的密钥 ARN 才能访问另一个 AWS 账户中的密钥。

  '{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecret-asd123:SecretString:password}}'

如果指定以下分段,将会从另一个 AWS 账户中检索版本阶段值为 AWSPENDING 的 MySecret 密钥版本的 password 值。请注意,您必须指定完整的密钥 ARN 才能访问另一个 AWS 账户中的密钥。

  '{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecretName-asd123:SecretString:password:AWSPENDING}}'