更新 ECS 容器中的环境变量 Secret

Wil*_*ill 10 environment amazon-web-services amazon-ecs

我正在为 ECS 部署一个任务定义,其中包含作为环境变量传递到正在运行的容器的机密。

这些密钥存储在 AWS Secrets Manager 中,并且容器使用所需的正确 IAM 策略成功描述了这些密钥。凉爽的。

但是,假设我要在 Secret Manager 中更新我的密钥,并更改密码或其他内容 - 我应该在 ECS 中做什么来确保容器获取此更新的密钥值?

我知道您不需要注册新的任务定义,因为状态没有改变 - 我真的想重新启动我的容器..也许我根本不需要做任何事情?

lch*_*ann 6

您通过在 ECS 任务定义 (文档)中引用 AWS Secrets Manager 密钥来检索它们。

现在您想知道,当您更新机密时,如何更新 ECS 容器,它们如何获取新的机密值?

您真的需要重新启动它们吗?

是的,您确实必须重新启动容器。

AWS 在文档中对此提供了答案:ECS 文档 > 任务定义 > 任务定义用例 > 将敏感数据传递到容器 > 通过环境变量检索机密 > 使用 Secrets Manager (注意事项下的第一个要点)

  • 当容器最初启动时,敏感数据会被注入到容器中。
  • 如果密钥随后更新或轮换,容器不会自动接收更新的值。
  • 您必须启动新任务,或者(如果您的任务是服务的一部分)您可以更新服务并使用强制新部署选项强制服务启动新任务。

为了避免这种手动工作,您可以...

a) 自动化- 通过创建 CloudWatch Event 规则,该规则侦听该密钥的更改并触发 Lambda 函数,从而强制 ECS 任务进行新部署。[受到推崇的]

解决方案:

  1. Secrets Manager 密钥已更新
  2. 发出 CloudWatch 事件:“秘密‘XYZ’已更改!”
  3. TODOCloudWatch Event 规则触发事件并调用 Lambda 函数
  4. TODOLambda 函数进行 ECS API 调用以强制给定服务进行新部署
  5. 与此 ECS 服务关联的容器将停止并重新启动。当容器重新启动时,它们会收到新的秘密。

先决条件: TODO您必须使用 CloudTrail(因为 Secrets Manager 本身不发出事件)。本指南解释了整个解决方案:

完整指南: 使用 CloudWatch Events + Lambda 更新容器密钥

为什么我推荐这个解决方案?
->它使您的“无代码”解决方案能够进行秘密管理,通过任务定义文件使用 ECS 秘密注入,使您的代码库保持整洁和小。

b) 动态检索秘密- 通过在每次需要时在应用程序代码中请求它。
为了使您不要向 SecretsManager API 发出数百万个请求(成本高、性能低!),AWS 建议使用客户端缓存并将其包含在所有代码示例中。

Java 示例:

public class SampleClass implements RequestHandler<String, String> {

    private final SecretCache cache  = new SecretCache();

    @Override public String handleRequest(String secretId,  Context context) {
        final String secret  = cache.getSecretString(secretId);
        // Use the secret, return success;
    }
}
Run Code Online (Sandbox Code Playgroud)

从 AWS Secrets Manager 接收密钥 - 文档


如果您正在处理轮换秘密:

上一节中的两个选项同样适用。


如果机密位于另一个 AWS 账户中:

您将需要实现CrossAccountEventDelivery,以便您得到“秘密已更改!” 您的账户中也有事件,以触发您的 Lambda。

此事件传递可以像仅转发您的特定秘密更改的事件一样具体。


aks*_*kap 3

ECS 任务定义中的 Secret 仅在容器启动时注入。为此,您需要在容器实例上拥有 >=1.22.0 的 ECS 代理版本。

因此,在上述场景中,您可以使用以下选项之一:

  • 强制进行新部署(这将导致再次获取机密)
  • 注册一个新的任务定义(从逻辑上讲,定义的状态实际上已经改变,因为依赖的参数/秘密被修改了——只是您引用了一个与应用程序代码不紧密耦合的外部存储)