

# 获取 Secrets Manager 中的密钥或密钥值
<a name="dynamic-references-secretsmanager"></a>

Secrets Manager 是一项便于您安全存储和管理密钥的服务，例如数据库凭证、密码和第三方 API 密钥等。使用 Secrets Manager，您可以集中存储和控制对这些密钥的访问，以便使用对 Secrets Manager 的 API 调用来替换代码中的硬编码凭证（包括密码），以编程方式检索密钥。有关更多信息，请参阅《AWS Secrets Manager 用户指南》中的[什么是 AWS Secrets Manager？](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)。

要在 CloudFormation 模板中使用 Secrets Manager 中存储的全部密钥或密钥值，请使用 `secretsmanager` 动态引用。

## 最佳实践
<a name="dynamic-references-secretsmanager-best-practices"></a>

在 CloudFormation 模板中使用 Secrets Manager 动态引用时，请遵循以下最佳实践：
+ **对 CloudFormation 模板使用无版本引用**：将凭证存储在 Secrets Manager 中并使用动态引用而不指定 `version-stage` 或 `version-id` 参数，以支持正确的密钥轮换工作流程。
+ **利用自动轮换**：使用 Secrets Manager 的自动轮换功能，结合无版本动态引用进行凭证管理。这可以确保您的凭证得到定期更新，而无需更改模板。有关更多信息，请参阅[轮换 AWS Secrets Manager 密钥](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html)。
+ **谨慎使用带版本引用**：仅为测试或回滚等特定场景指定显式的 `version-stage` 或 `version-id` 参数。

## 注意事项
<a name="dynamic-references-secretsmanager-considerations"></a>

使用 `secretsmanager` 动态引用时，需要记住以下重要注意事项：
+ CloudFormation 不会追踪之前的部署中使用了哪个版本的密钥。在实现动态引用之前，请认真规划您的密钥管理策略。尽量使用无版本引用，以利用自动密钥轮换功能。在更改动态引用配置时（例如从无版本动态引用改换为带版本动态引用，反之亦然）时，监控和验证资源更新。
+ 仅更新 Secrets Manager 中的密钥值不会自动触发 CloudFormation 检索新值。CloudFormation 仅在创建或更新资源修改包含动态引用的资源时检索密钥值。

  例如，假设您的模板包含 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html) 资源，其中 `MasterPassword` 属性设置为 Secrets Manager 动态引用。使用此模板创建堆栈后，需要在 Secrets Manager 中更新密钥值。但是，`MasterPassword` 属性保留了旧密码值。

  要应用新密钥值，需修改 CloudFormation 模板中的 `AWS::RDS::DBInstance` 资源并执行堆栈更新。

  为避免将来执行这种手动过程，可考虑使用 Secrets Manager 自动轮换密钥。
+ 自定义资源中目前不支持对安全值的动态引用，例如 `secretsmanager`。
+ `secretsmanager` 动态引用可用于所有资源属性。使用 `secretsmanager` 动态引用表示 Secrets Manager 和 CloudFormation 日志均不应保留任何已解析的密钥值。但是，密钥值可能会显示在正在其资源中使用的服务中。检查您的使用情况，以避免泄露密钥数据。

## 权限
<a name="dynamic-references-secretsmanager-permissions"></a>

要指定存储在 Secrets Manager 中的密钥，您必须有权为该密钥调用 [https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)。

## 引用模式
<a name="dynamic-references-secretsmanager-pattern"></a>

要在 CloudFormation 模板中引用 Secrets Manager 密钥，请使用以下 `secretsmanager` 引用模式。

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

`secret-id`  
密钥的名称或 ARN。  
要访问您的 AWS 账户中的密钥，只需指定密钥名称即可。要访问其他 AWS 账户中的密钥，请指定密钥的完整 ARN。  
必需。

`secret-string`  
`SecretString` 是唯一受支持的值。默认值为 `SecretString`。

`json-key`  
要检索其值的键值对的键名称。如果您不指定 `json-key`，CloudFormation 会检索整个密钥文本。  
此分段不得包含冒号字符 ( `:` )。

`version-stage`  
要使用的密钥版本的暂存标签。Secrets Manager 在轮换过程中使用暂存标注来跟踪不同的版本。如果您使用 `version-stage`，则不要指定 `version-id`。如果您既未指定 `version-stage`，也未指定 `version-id`，则原定设置将为 `AWSCURRENT` 版本。  
此分段不得包含冒号字符 ( `:` )。

`version-id`  
要使用的密钥版本的唯一标识符。如果指定 `version-id`，则不要指定 `version-stage`。如果您既未指定 `version-stage`，也未指定 `version-id`，则原定设置将为 `AWSCURRENT` 版本。  
此分段不得包含冒号字符 ( `:` )。

## 示例
<a name="dynamic-references-secretsmanager-examples"></a>

**Topics**
+ [从密钥中检索用户名和密码值](#dynamic-references-secretsmanager-examples-user-name-and-password)
+ [检索整个 SecretString](#dynamic-references-secretsmanager-examples-entire-secretstring)
+ [从密钥的特定版本中检索值](#dynamic-references-secretsmanager-examples-specific-version)
+ [从另一个 AWS 账户检索密钥](#dynamic-references-secretsmanager-examples-secrets-from-another-account)

### 从密钥中检索用户名和密码值
<a name="dynamic-references-secretsmanager-examples-user-name-and-password"></a>

以下 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html) 示例检索在 `MySecret` 密钥中存储的用户名和密码值。此示例展示了无版本动态引用的推荐模式，该模式自动使用 `AWSCURRENT` 版本且支持 Secrets Manager 轮换工作流程，而无需更改模板。

#### JSON
<a name="dynamic-references-secretsmanager-examples-user-name-and-password.json"></a>

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

#### YAML
<a name="dynamic-references-secretsmanager-examples-user-name-and-password.yaml"></a>

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

### 检索整个 SecretString
<a name="dynamic-references-secretsmanager-examples-entire-secretstring"></a>

以下动态引用检索 `MySecret` 的 `SecretString`。

```
{{resolve:secretsmanager:MySecret}}
```

或者：

```
{{resolve:secretsmanager:MySecret::::}}
```

### 从密钥的特定版本中检索值
<a name="dynamic-references-secretsmanager-examples-specific-version"></a>

以下动态引用检索 `MySecret` 的 `AWSPREVIOUS` 版本的 `password` 值。

```
{{resolve:secretsmanager:MySecret:SecretString:password:AWSPREVIOUS}}
```

### 从另一个 AWS 账户检索密钥
<a name="dynamic-references-secretsmanager-examples-secrets-from-another-account"></a>

以下动态引用检索另一个 AWS 账户中的 `MySecret` 的 `SecretString`。您必须指定完整的密钥 ARN 才能访问其他 AWS 账户中的密钥。

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

以下动态引用检索另一个 AWS 账户中的 `MySecret` 的 `password` 值。您必须指定完整的密钥 ARN 才能访问其他 AWS 账户中的密钥。

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