【问题标题】:how to use aws secret manager values of a postgres database in terraform ecs task definition如何在 terraform ecs 任务定义中使用 postgres 数据库的 aws secret manager 值
【发布时间】:2021-10-12 16:47:15
【问题描述】:

我有一个使用 terraform、docker compose 的 django 应用程序下面的 settings.py 文件,我试图在 ecs 任务定义中获取存储在 aws secret manager 中的数据库的值

settings.py

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "NAME": os.environ.get("POSTGRES_DB"),
        "USER": os.environ.get("POSTGRES_USER"),
        "PASSWORD": os.environ.get("POSTGRES_PASSWORD"),
        "HOST": os.environ.get("POSTGRES_HOST"),
        "PORT": 5432,
    }
}

任务定义

resource "aws_ecs_task_definition" "ecs_task_definition" {
  family                   = "ecs_container"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = 256                      
  memory                   = 512
  execution_role_arn       = data.aws_iam_role.fargate.arn
  task_role_arn            = data.aws_iam_role.fargate.arn
  container_definitions = jsonencode([
    {
      "name"         : "ecs_test_backend",
      "image"        : "${aws_ecr_repository.ecr_repository.repository_url}:latest",
      "cpu"          : 256,
      "memory"       : 512,
      "essential"    : true,
      "portMappings" : [
        {
          containerPort = 8000
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-region": "us-east-1",
          "awslogs-group": "/ecs/ecs_test_backend",
          "awslogs-stream-prefix": "ecs"
        }
      }
      "environment"   : [
        {
          "name": "POSTGRES_DB",
          "value": "${var.POSTGRES_NAME}" <=== HERE
        },
        {
          "name": "POSTGRES_PASSWORD",
          "value": "${var.POSTGRES_PASSWORD}"  <=== HERE
        },
        {
          "name": "POSTGRES_USERNAME",
          "value": "${var.POSTGRES_USERNAME}"  <=== HERE
        },
        {
          "name": "POSTGRES_PORT",
          "value": "${var.POSTGRES_PORT}"  <=== HERE
        },
        {
          "name": "POSTGRES_HOST",
          "value": "${var.POSTGRES_HOST}"  <=== HERE
        },
      ]
    }
  ])
}

变量

variable "POSTGRES_PASSWORD" {
    type = string
    default = "somepassword"
}

上面的变量与创建 postgres rds 实例时使用的相同。

var.XXX 下面的配置似乎不起作用,因为任务日志返回 psycopg2.OperationalError: FATAL: password authentication failed for user "root"

这可能是因为它无法读取该值。

以上是使用 Terraform 和 ECS 从 AWS Secret Manager 中获取价值的正确方法吗?

【问题讨论】:

  • 如果您展示了如何设置var.POSTGRES_PASSWORD 和其他环境变量,那么回答这个问题会更容易。理想情况下,您问题中的代码应该形成一个minimal reproducible example,允许其他人运行它并查看它在哪里出现与您遇到的相同错误。
  • @ydaetskcoR 我确实更新了那个变量它只是一个字符串
  • 如果 DB 用户名 root 正在进入容器,那么听起来您设置的值是正确的。您确定您使用的是正确的用户名/密码吗?数据库在哪里运行?是否在 RDS 上运行?

标签: python django postgresql amazon-web-services terraform


【解决方案1】:

您应该使用 ECS 任务的敏感数据处理功能,记录在 here

您可以将环境变量从任务定义的 environment 块移动到 secrets 块,并提供密钥的 ARN 而不是值。然后,ECS 容器将在启动容器时读取这些机密,并将它们设置在容器的环境中。

【讨论】:

  • 马克,您能否举例说明该部分的代码是什么样的,您是指每个部分的每个秘密还是一个可以处理所有 env 变量的单个 ARN?我在这个问题上被阻止了一个星期,实际上我之前读过那个链接。 (非常感谢您的宝贵时间)
  • @feldobadix 这个答案真的解决了你的问题吗?您的评论不建议,但您已将其标记为已接受。一个公认的答案应该是它确实解决了您的问题。如果你想奖励/承认一个有用的答案,那么这应该是一个赞成票(你可以从 15 个声望开始)。
  • @MarkB 我认为这并不能真正回答问题。是的,他们应该使用secrets 将诸如密码之类的秘密传递给任务,但它仍会将其作为环境变量公开,因此他们在应用程序中读取它的方式是正确的,问题更多在于@987654326 @ 已设置,您无法从问题的当前状态中分辨出来。
  • @ydaetskcoR AWS 文档建议使用secrets 作为@MarkB 的建议,但是当您查看控制台以及启动任务时作为环境变量传入的内容时,它是空的,我问的原因他举个例子的代码。上面的配置确实显示了 env 变量,但是当任务启动时出现了一个新的错误postgres connection failed for user "root",我发布了这个问题:这里是stackoverflow.com/questions/68688635/…。我被困了几个星期,似乎找不到解决方案
  • @ydaetskcoR ECS 将在运行时读取秘密值并将其作为 容器 环境变量注入。这与原始问题中发生的 local 环境变量完全不同。不再需要本地环境变量。
猜你喜欢
  • 2022-01-27
  • 2016-05-04
  • 2021-01-19
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多