使用动态引用以指定模板值
动态引用提供了一种简洁、强大的方法,用于指定在堆栈模板内的其他服务中存储和管理的外部值,例如堆栈模板中的 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-secure
和secretsmanager
。
请不要创建将反斜杠 (\) 用作最终值的动态参考。AWS 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 参数。有关更多信息,请参阅 AWS Systems Manager 用户指南 中的 AWS Systems Manager Parameter Store。
-
secretsmanager
:AWS 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
-
一个整数,指定要使用的参数的版本。您必须指定确切的版本。目前,您无法指定 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-secure
和secretsmanager
。 -
如果 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-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: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}}'