使用动态引用以指定模板值
动态引用提供了一种简洁、强大的方法,用于指定在堆栈模板内的其他服务中存储和管理的外部值,例如堆栈模板中的 Systems Manager Parameter Store。当您使用动态引用时,CloudFormation 会在堆栈和更改集合操作期间在必要时检索指定引用的值。
CloudFormation 目前支持以下动态引用模式:
ssm(对于在 Amazon Systems Manager Parameter Store 中存储的纯文本值)
ssm-secure(对于在 Amazon Systems Manager Parameter Store 中存储的安全字符串)
secretsmanager(对于在 Amazon Secrets Manager 存储中的整个密钥或特定密钥值)
使用动态引用时的注意事项
下面是使用动态引用时应考虑的注意事项:
我们强烈建议不要在作为资源主标识符组成部分的资源属性中包含动态引用或任何敏感数据。
当动态引用参数包含在构成主资源标识符的属性中时,CloudFormation 可能会使用主资源标识符中的实际纯文本值。此资源 ID 可能会出现在任何派生输出或目标中。
要确定哪些资源属性构成资源类型的主标识符,请参阅该资源的资源参考文档。在 Return values(返回值)部分中,Ref 函数返回值表示组成资源类型的主标识符的资源属性。
您最多可以在堆栈模板中包含 60 个动态引用。
对于转换,例如
AWS::Include和AWS::Serverless,Amazon CloudFormation 在调用任何转换之前不解析动态引用。相反,Amazon CloudFormation 会将动态引用的文本字符串传递给转换。当使用模板执行更改集时,将会解析动态引用(包括那些作为转换结果插入到已处理模板中的引用)。自定义资源中目前不支持安全值的动态引用,例如
ssm-secure和secretsmanager。
请不要创建将反斜杠 (\) 用作最终值的动态参考。Amazon CloudFormation 无法解析这些参考,而导致资源失败。
在堆栈模板中指定动态引用
动态引用遵循以下模式:
'{{resolve:service-name:reference-key}}'
- service-name
-
指定要在其中存储和管理值的服务。
必填项。
目前,有效值包括:
ssm:Systems Manager Parameter Store 纯文本参数。ssm-secure:Systems Manager Parameter Store 安全字符串参数。注意 目前,
cn-north-1和cn-northwest-1区域中的 Systems Manager 不支持 SecureString 参数。有关更多信息,请参阅 Amazon Systems Manager 用户指南 中的 Amazon Systems Manager Parameter Store。
secretsmanager:Amazon Secrets Manager 密钥。
- reference-key
-
引用键。根据动态引用的类型,引用键可以包括多个分段。
必需。
SSM 参数
使用 ssm 动态引用,将在类型为 String 或 StringList 的 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
一个整数,指定要使用的参数的版本。如果您没有指定确切的版本,CloudFormation 将在创建或更新堆栈时使用参数的最新版本。有关更多信息,请参阅 Amazon 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。有关更多信息,请参阅Amazon Systems Manager 用户指南中的控制对 Systems Manager 参数的访问权限。
使用 ssm 动态引用模式时需要注意的其他注意事项:
目前,CloudFormation 不支持跨账户 SSM 参数访问。
对于自定义资源,CloudFormation 在将请求发送到自定义资源之前解析
ssm动态引用。有关更多信息,请参阅自定义资源。-
CloudFormation 不支持在动态引用中使用参数标签或公有参数。
参数标签是用户定义的别名,帮助管理参数的不同版本。有关更多信息,请参阅Amazon Systems Manager 用户指南中的标记参数。
公有参数是 Amazon 服务提供的用于与该服务一起使用的参数,存储在 Amazon Systems Manager Parameter Store 中。有关公有参数的示例,请参阅Amazon Elastic Container Service Developer Guide中的检索 Amazon ECS 优化的 AMI 元数据。
CloudFormation 目前不支持对动态引用进行偏差检测。对于尚未指定参数版本的
ssm动态引用,建议您在更新 SSM 中的参数版本时,还要对包含ssm动态引用的任何堆栈执行堆栈更新操作,以获取最新的参数版本。
SSM 安全字符串参数
使用 ssm-secure 动态引用模式在模板中指定 Amazon Systems Manager SecureString 类型参数。对于 ssm-secure 动态引用,Amazon CloudFormation 绝不会存储实际参数值。Amazon CloudFormation 在堆栈和更改集的创建和更新操作期间访问参数值。目前,只能将安全字符串参数用于支持 ssm-secure 动态引用模式的资源属性。
安全字符串参数是需要以安全的方式存储和引用的任何敏感数据。也就是说,您不希望用户以明文形式更改或引用的数据,例如密码或许可证密钥。有关安全字符串的更多信息,请参阅 Amazon 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
一个整数,指定要使用的参数的版本。您必须指定确切的版本。目前,您无法指定 Amazon CloudFormation 使用参数的最新版本。有关更多信息,请参阅 Amazon 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-secure和secretsmanager。 -
如果 CloudFormation 必须回滚堆栈更新,则如果先前指定的安全字符串参数版本不再可用,则该更新回滚操作将失败。在这种情况下,请执行以下操作之一:
使用
CONTINUE_UPDATE_ROLLBACK跳过资源。在 Systems Manager Parameter Store 中重新创建安全字符串参数,并更新它,直到参数版本达到模板中使用的版本。然后使用
CONTINUE_UPDATE_ROLLBACK而无需跳过资源。
目前,Amazon CloudFormation 不支持跨账户 SSM 参数访问。
-
CloudFormation 不支持在动态引用中使用参数标签或公有参数。
参数标签是用户定义的别名,帮助管理参数的不同版本。有关更多信息,请参阅Amazon Systems Manager 用户指南中的标记参数。
公有参数是 Amazon 服务提供的用于与该服务一起使用的参数,存储在 Amazon Systems Manager Parameter Store 中。有关公有参数的示例,请参阅Amazon Elastic Container Service Developer Guide中的检索 Amazon ECS 优化的 AMI 元数据。
对安全字符串支持动态参数模式的资源
支持 ssm-secure 动态引用模式的资源目前包括:
| 资源 | 属性类型 | 属性 |
|---|---|---|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Secrets Manager 密钥
使用 secretsmanager 动态引用可检索在 Amazon Secrets Manager 中存储的全部密钥或密钥值,以便在模板中使用。密钥可以是数据库凭证、密码、第三方 API 密钥,甚至是任意文本。使用 Secrets Manager,您可以集中存储和控制对这些密钥的访问权限。Secrets Manager 允许您将代码中的硬编码凭证(包括密码)替换为对 Secrets Manager 的 API 调用,以便以编程方式检索密钥。有关更多信息,请参阅Amazon Secrets Manager 用户指南中的什么是 Amazon 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 自动轮换受保护服务或数据库的密钥。有关更多信息,请参阅轮换您的 Amazon Secrets Manager 密钥。
自定义资源中目前不支持安全值的动态引用,例如
secretsmanager。
所需权限
要指定一个存储在 Secrets Manager 中的密钥,您必须有权为指定的密钥调用 GetSecretValue。
引用模式
对于 Secrets Manager 密钥,reference-key 分段由多个分段组成,包括密钥 id、密钥值键、版本阶段和版本 id。请使用以下模式:
{{resolve:secretsmanager:secret-id:secret-string:json-key:version-stage:version-id}}
- secret-id
-
用作密钥的唯一标识符的名称或 Amazon资源名称 (ARN)。
要访问您的 Amazon 账户中的密钥,您只需指定密钥名称。要访问其他 Amazon 账户中的密钥,请指定密钥的完整 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-name 和 json-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::EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE}}'
如果指定以下分段,将会从另一个 Amazon 账户中检索版本阶段值为 AWSCURRENT 的 MySecret 密钥版本的整个 SecretString。请注意,您必须指定完整的密钥 ARN 才能访问另一个 Amazon 账户中的密钥。
'{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecret-asd123}}'
如果指定以下分段,将会从另一个 Amazon 账户中检索版本阶段值为 AWSCURRENT 的 MySecret 密钥版本的 password 值。请注意,您必须指定完整的密钥 ARN 才能访问另一个 Amazon 账户中的密钥。
'{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecret-asd123:SecretString:password}}'
如果指定以下分段,将会从另一个 Amazon 账户中检索版本阶段值为 AWSPENDING 的 MySecret 密钥版本的 password 值。请注意,您必须指定完整的密钥 ARN 才能访问另一个 Amazon 账户中的密钥。
'{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecretName-asd123:SecretString:password:AWSPENDING}}'