使用动态引用以指定模板值 - 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:SecretString: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}}'