如何在 ECS 任务中将 rds.DatabaseCluster 机密作为环境变量传递

Posted

技术标签:

【中文标题】如何在 ECS 任务中将 rds.DatabaseCluster 机密作为环境变量传递【英文标题】:How to pass rds.DatabaseCluster secrets as environment variable in a ECS Task 【发布时间】:2020-11-13 04:41:41 【问题描述】:

我正在尝试将 RDS Aurora 凭据设置为 ECS 任务的环境变量。 最初我将它作为纯文本传递给environments。 我知道正确的做法是使用secrets,但ApplicationLoadBalancedTaskImageOptions 期望Secretrds.DatabaseCluster 返回另一种类型。 在这种情况下管理凭据的正确方法是什么?

db 是一个 rds.DatabaseCluster 实例
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
                image=ecs.ContainerImage.from_registry("sonarqube:8.2-community"),
                container_port=9000,
                # FIXME: by documentation this is the right way to pass creds, however this fail, the database secret is not the same type than the expected
                # secrets=
                #     "sonar.jdbc.password": ecs.Secret.from_secrets_manager(self.db.secret)
                # ,
                environment=
                    'sonar.jdbc.url': url,
                    "sonar.jdbc.username": username,
                    "sonar.jdbc.password": self.db.secret.secret_value_from_json("password").to_string() #plaintext, FIXME
                
            )

【问题讨论】:

【参考方案1】:

真是个迷!

我前两天发了一篇关于这个话题的文章:

https://medium.com/@mchlfchr/i-tell-you-a-secret-provide-database-credentials-to-an-ecs-fargate-task-in-aws-cdk-339df4e3d071

在这里您可以清楚地发现使用机密和环境变量之间的区别。

【讨论】:

【参考方案2】:

如果您想将其作为密钥传递,您首先必须将值存储在 AWS SecretsManager 或 AWS Parameter Store 中。然后,您从这两个服务之一传递密钥的 ARN,作为 ECS 任务定义中的值,ECS 将在实例化容器时自动从 SecretsManager 或 Parameter Store 中提取实际值。这记录在here。

【讨论】:

【参考方案3】:

如果您想使用秘密存储中的值,那么它应该 secrets 而不是环境变量。

将环境变量替换为secrets,如下所示

 "secrets": [
              
               "name": "MY_KEY",
               "valueFrom": "arn:aws:secretsmanager:us-west-2:12345656:secret:demo-0Nlyli"
                
            ]

只需放置 ARN,ECS 就会在运行时注入值。

设置你需要的环境变量

"environment": [
                
                    "name": "KEY",
                    "value": "VALUE"
                
            ]

在你的情况下

"environment": [
                
                    "name": "sonar.jdbc.url",
                    "value": "some-url"
                
            ]

【讨论】:

【参考方案4】:

使用来自@mchlfchr 的 ts 示例,我在 python 中按如下方式工作

创建角色并授予对数据库凭据的读取权限

        #Create iam Role for Task
        self.task_role = iam.Role(
            self,
            id= "SonarTaskRole",
            role_name= "SonarTaskRole",
            assumed_by= iam.ServicePrincipal(service= "ecs-tasks.amazonaws.com"),
            managed_policies= [
                iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AmazonECSTaskExecutionRolePolicy")
            ]
        )
        #Grant permission to the Task to read secret from SecretsManager
        self.db_secret.grant_read(self.task_role)

并作为秘密传递:

                secrets=
                    "sonar.jdbc.username": ecs.Secret.from_secrets_manager(self.db_secret, field="username"),
                    "sonar.jdbc.password": ecs.Secret.from_secrets_manager(self.db_secret, field="password")
                ,

【讨论】:

以上是关于如何在 ECS 任务中将 rds.DatabaseCluster 机密作为环境变量传递的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 terraform 在 ecs 任务定义中指定环境变量?

如何允许ECS任务访问RDS

ECS 任务。如何在容器中使用 AWS CLI

什么是 ECS 任务组,如何创建?

如何在 ECS Fargate 任务定义中配置主机名

如何在 AWS ECS 中扩展任务/容器