You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Terraform ECS任务定义中使用AWS Secret Manager存储的Postgres数据库值

首先明确:你当前的配置不是从AWS Secrets Manager获取值的正确方式,同时还存在低级的变量名不匹配问题,两者共同导致了报错。


问题根因

  1. 环境变量名不匹配:你的settings.py中读取的数据库用户环境变量是POSTGRES_USER,但ECS任务定义里注入的环境变量名是POSTGRES_USERNAME,Django读取不到对应值就默认使用了内置的root用户,直接触发密码验证失败报错。
  2. 未对接AWS Secrets Manager:你现在直接用Terraform变量传递敏感值的方式,会把密码等敏感信息明文存在Terraform状态文件中,存在泄露风险,也完全没有调用Secrets Manager拉取配置的逻辑。

正确配置步骤

1. 前置权限配置

给你的ECS任务执行角色(即代码中引用的data.aws_iam_role.fargate)附加以下权限,确保ECS有权限拉取Secrets Manager的密钥:

resource "aws_iam_role_policy" "secrets_access" {
  name = "ecs-secrets-access"
  role = data.aws_iam_role.fargate.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "secretsmanager:GetSecretValue",
          "kms:Decrypt" # 若你的Secrets Manager密钥使用了自定义KMS加密则需要加这行
        ]
        Effect   = "Allow"
        Resource = "arn:aws:secretsmanager:<你的AWS区域>:<你的AWS账号ID>:secret:<你的密钥名>-*" # 替换为你的密钥实际ARN
      }
    ]
  })
}
2. Terraform中添加Secrets Manager数据源
# 读取已创建的数据库密钥
data "aws_secretsmanager_secret" "db_creds" {
  name = "<你的Secrets Manager密钥名称>" # 替换为实际密钥名
}

data "aws_secretsmanager_secret_version" "db_creds" {
  secret_id = data.aws_secretsmanager_secret.db_creds.id
}
3. 修改ECS任务定义

把原来environment中的敏感配置移到secrets字段中,同时修正变量名:

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
      "environment"   : [
        {
          "name": "POSTGRES_PORT",
          "value": "${var.POSTGRES_PORT}"
        },
        {
          "name": "POSTGRES_HOST",
          "value": "${var.POSTGRES_HOST}"
        },
      ],
      # 敏感配置从Secrets Manager拉取
      "secrets": [
        {
          "name": "POSTGRES_DB",
          "valueFrom": "${data.aws_secretsmanager_secret.db_creds.arn}:POSTGRES_DB::"
        },
        {
          "name": "POSTGRES_PASSWORD",
          "valueFrom": "${data.aws_secretsmanager_secret.db_creds.arn}:POSTGRES_PASSWORD::"
        },
        # 修正变量名和settings.py对应
        {
          "name": "POSTGRES_USER",
          "valueFrom": "${data.aws_secretsmanager_secret.db_creds.arn}:POSTGRES_USER::"
        }
      ]
    }
  ])
}

注意事项

  • 请确保Secrets Manager中存储的密钥键名和valueFrom中后缀的键名完全一致。
  • 生产环境不要在Terraform变量的default字段中硬编码敏感信息。

内容的提问来源于stack exchange,提问作者feldo badix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 06:18:01