如何在Terraform ECS任务定义中使用AWS Secret Manager存储的Postgres数据库值
首先明确:你当前的配置不是从AWS Secrets Manager获取值的正确方式,同时还存在低级的变量名不匹配问题,两者共同导致了报错。
问题根因
- 环境变量名不匹配:你的
settings.py中读取的数据库用户环境变量是POSTGRES_USER,但ECS任务定义里注入的环境变量名是POSTGRES_USERNAME,Django读取不到对应值就默认使用了内置的root用户,直接触发密码验证失败报错。 - 未对接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
相关产品推荐
相关产品推荐

