

# 通过 Amazon ECS 环境变量传递 Secrets Manager 密钥
<a name="secrets-envvar-secrets-manager"></a>

当您将密钥作为环境变量注入时，可以指定密钥的完整内容、密钥内的特定 JSON 键。这将帮助您控制提供给容器的敏感数据。有关密钥版本控制的更多信息，请参阅《Amazon Secrets Manager 用户指南》**中的 [What's in a Secrets Manager secret?](https://docs.amazonaws.cn/secretsmanager/latest/userguide/whats-in-a-secret.html#term_version)。

在使用环境变量将 Secrets Manager 密钥注入容器时，应考虑以下事项。
+ 最初启动容器时，会将敏感数据注入容器中。如果随后更新或轮换密钥，则容器将不会自动接收更新后的值。您必须启动新任务，或者如果您的任务是服务的一部分，则可以更新服务并使用**强制新部署**选项来强制服务启动新任务。
+ 在容器上运行的应用程序以及容器日志和调试工具可以访问环境变量。
+ 对于 Amazon Fargate 上的 Amazon ECS 任务，请考虑以下事项：
  + 要将密钥的完整内容注入为环境变量或注入到日志配置中，您必须使用平台版本 `1.3.0` 或更高版本的平台。有关信息，请参阅[适用于 Amazon ECS 的 Fargate 平台版本](platform-fargate.md)。
  + 要将特定 JSON 密钥或密钥版本注入为环境变量或注入到日志配置中，您必须使用平台版本 `1.4.0` 或更高版本（Linux）或者 `1.0.0`（Windows）。有关信息，请参阅[适用于 Amazon ECS 的 Fargate 平台版本](platform-fargate.md)。
+ 对于 EC2 上的 Amazon ECS 任务，应注意以下事项：
  + 要使用特定的 JSON 密钥或密钥版本注入密钥，容器实例必须具有版本 `1.37.0` 或更高版本的容器代理。但是，我们建议使用最新的容器代理版本。有关检查您的代理版本并更新到最新版本的信息，请参阅[更新 Amazon ECS 容器代理](ecs-agent-update.md)。

    要将密钥的完整内容注入为环境变量或将密钥注入日志配置中，您的容器实例必须具有版本 `1.22.0` 或更高版本的容器代理。
+ 使用接口 VPC 端点增强安全控制措施，并通过私有子网连接到 Secrets Manager。您必须为 Secrets Manager 创建接口 VPC 端点。有关 VPC 端点的信息，请参阅《Amazon Secrets Manager 用户指南》**中的[创建 VPC 端点](https://docs.amazonaws.cn/secretsmanager/latest/userguide/setup-create-vpc.html)。有关使用 Secrets Manager 和 Amazon VPC 的更多信息，请参阅[如何在 Amazon VPC 内连接到 Secrets Manager 服务](https://www.amazonaws.cn/blogs//security/how-to-connect-to-aws-secrets-manager-service-within-a-virtual-private-cloud/)。
+ 对于配置为使用 `awslogs` 日志记录驱动程序的 Windows 任务，您还必须在容器实例上设置 `ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE` 环境变量。使用以下语法：

  ```
  <powershell>
  [Environment]::SetEnvironmentVariable("ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE", $TRUE, "Machine")
  Initialize-ECSAgent -Cluster <cluster name> -EnableTaskIAMRole -LoggingDrivers '["json-file","awslogs"]'
  </powershell>
  ```
+ 任务定义必须使用具有 Secrets Manager 额外权限的任务执行角色。有关更多信息，请参阅 [Amazon ECS 任务执行 IAM 角色](task_execution_IAM_role.md)。

## 创建 Amazon Secrets Manager 密钥
<a name="secrets-envvar-secrets-manager-create-secret"></a>

您可以使用 Secrets Manager 控制台为您的敏感数据创建密钥。有关更多信息，请参阅**《Amazon Secrets Manager 用户指南》中的[创建 Amazon Secrets Manager 密钥](https://docs.amazonaws.cn/secretsmanager/latest/userguide/create_secret.html)。

## 将环境变量添加到容器定义中
<a name="secrets-envvar-secrets-manager-update-container-definition"></a>

在容器定义中，可以指定以下内容：
+ `secrets` 对象，该对象包含要在容器中设置的环境变量名称
+ Secrets Manager 密钥的 Amazon 资源名称（ARN）。
+ 其他参数，这些参数包含要提供给容器的敏感数据

以下示例显示必须为 Secrets Manager 密钥指定的完整语法。

```
arn:aws:secretsmanager:region:aws_account_id:secret:secret-name:json-key:version-stage:version-id
```

下一部分介绍了其他参数。这些参数是可选的，但如果不使用它们，则必须包含冒号 `:` 以使用默认值。下面提供了示例，以便您了解更多上下文。

`json-key`  
使用要设置为环境变量值的值指定密钥-值对中密钥的名称。仅支持 JSON 格式的值。如果未指定 JSON 密钥，则使用密钥的完整内容。

`version-stage`  
指定要使用的密钥版本的暂存标签。如果指定了版本的暂存标签，则无法指定版本 ID。如果未指定版本阶段，则默认行为是使用 `AWSCURRENT` 暂存标签检索密钥。  
暂存标签用于在更新或轮换密钥的各个版本时对其进行跟踪。密钥的每个版本均有一个或多个暂存标签和一个 ID。

`version-id`  
指定要使用的密钥版本的唯一标识符。如果指定了版本 ID，则无法指定版本暂存标签。如果未指定版本 ID，则默认行为是使用 `AWSCURRENT` 暂存标签检索密钥。  
版本 ID 用于在更新或轮换密钥的各个版本时对其进行跟踪。密码的每个版本均有一个 ID。有关更多信息，请参阅 *Amazon Secrets Manager 用户指南*中的 [Amazon Secrets Manager 主要术语和概念。](https://docs.amazonaws.cn/secretsmanager/latest/userguide/terms-concepts.html#term_secret)

### 示例容器定义
<a name="secrets-examples"></a>

以下示例说明了可用于在容器定义中引用 Secrets Manager 密钥的方法。

**Example 引用完整密钥**  
以下是任务定义的片段，其中显示引用 Secrets Manager 密钥的完全文本时的格式。  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-AbCdEf"
    }]
  }]
}
```
要从容器中访问此密钥的值，需要调用 `$environment_variable_name`。

**Example 引用完整密钥**  
以下是任务定义的片段，其中显示引用多个 Secrets Manager 密钥的完全文本时的格式。  

```
{
  "containerDefinitions": [{
     "secrets": [
      {
        "name": "environment_variable_name1",
         "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-AbCdEf"
      },
      {
        "name": "environment_variable_name2",
         "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-abcdef"
      },
      {
        "name": "environment_variable_name3",
        "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name-ABCDEF"
      }
    ]
  }]
}
```
要从容器中访问此密钥的值，需要调用 `$environment_variable_name1`、`$environment_variable_name2` 和 `$environment_variable_name3`。

**Example 引用密钥中的特定密钥**  
下面显示了 [get-secret-value](https://docs.amazonaws.cn/cli/latest/reference/secretsmanager/get-secret-value.html) 命令中的示例输出，其中显示了密钥的内容以及与之关联的版本暂存标签和版本 ID。  

```
{
    "ARN": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf",
    "Name": "appauthexample",
    "VersionId": "871d9eca-18aa-46a9-8785-981ddEXAMPLE",
    "SecretString": "{\"username1\":\"password1\",\"username2\":\"password2\",\"username3\":\"password3\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1581968848.921
}
```
通过在 ARN 的末尾指定密钥名称，引用容器定义中的上一个输出中的特定密钥。  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:username1::"
    }]
  }]
}
```

**Example 引用特定的密钥版本**  
下面显示了 [describe-secret](https://docs.amazonaws.cn/cli/latest/reference/secretsmanager/describe-secret.html) 命令中的示例输出，其中显示了密钥的未加密内容以及密钥的所有版本的元数据。  

```
{
    "ARN": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf",
    "Name": "appauthexample",
    "Description": "Example of a secret containing application authorization data.",
    "RotationEnabled": false,
    "LastChangedDate": 1581968848.926,
    "LastAccessedDate": 1581897600.0,
    "Tags": [],
    "VersionIdsToStages": {
        "871d9eca-18aa-46a9-8785-981ddEXAMPLE": [
            "AWSCURRENT"
        ],
        "9d4cb84b-ad69-40c0-a0ab-cead3EXAMPLE": [
            "AWSPREVIOUS"
        ]
    }
}
```
通过在 ARN 的末尾指定密钥名称，引用容器定义中的上一个输出中的特定版本暂存标签。  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf::AWSPREVIOUS:"
    }]
  }]
}
```
通过在 ARN 的末尾指定密钥名称，引用容器定义中的上一个输出中的特定版本 ID。  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:::9d4cb84b-ad69-40c0-a0ab-cead3EXAMPLE"
    }]
  }]
}
```

**Example 引用密钥的特定密钥和版本暂存标签**  
以下内容说明如何同时引用密钥中的特定密钥和特定版本暂存标签。  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:username1:AWSPREVIOUS:"
    }]
  }]
}
```
要指定特定密钥和版本 ID，请使用以下语法。  

```
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:region:aws_account_id:secret:appauthexample-AbCdEf:username1::9d4cb84b-ad69-40c0-a0ab-cead3EXAMPLE"
    }]
  }]
}
```

有关如何使用环境变量中指定的密钥创建任务定义的信息，请参阅 [使用控制台创建 Amazon ECS 任务定义](create-task-definition.md)。