Terraform配置SQS策略时Principal被替换为角色ID致访问拒绝问题
问题
我将应用部署在Fargate环境中,需要消费TRUCKDIM.fifo队列的消息。为实现该需求,我通过Terraform为ecs-task-role授予了该队列的全部权限,对应的Terraform代码如下:
resource "aws_sqs_queue" "queue_fifo-01" { name = var.name fifo_queue = var.fifo_queue fifo_throughput_limit = var.fifo_throughput_limit deduplication_scope = var.deduplication_scope content_based_deduplication = var.content_based_deduplication delay_seconds = var.delay_seconds max_message_size = var.max_message_size message_retention_seconds = var.message_retention_seconds receive_wait_time_seconds = var.receive_wait_time_seconds visibility_timeout_seconds = var.visibility_timeout_seconds kms_master_key_id = var.kms_master_key_id kms_data_key_reuse_period_seconds = var.kms_data_key_reuse_period_seconds redrive_policy = jsonencode({ deadLetterTargetArn = aws_sqs_queue.queue_fifo-02.arn maxReceiveCount = 10 }) policy = <<POLICY { "Version": "2012-10-17", "Id": "Policy1676302010732", "Statement": [ { "Sid": "Stmt1676302006390", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::995556942157:role/service-role/ecs-task-role" }, "Action": "sqs:*", "Resource": "arn:aws:sqs:us-west-2:995556942157:TRUCKDIM.fifo" } ] } POLICY }
注:ecs-task-role是通过Terraform创建的。
执行terraform plan时,Principal设置正确:
~ Principal = { ~ AWS = "AROA78POOLYTRE11KEEZA" -> "arn:aws:iam::995556942157:role/service-role/ecs-task-role" }
但执行terraform apply后,在AWS控制台查看TRUCKDIM.fifo队列的策略时,Principal被替换为角色ID字符串"AROA6OPZZLYFIE6IYBEF4":
{ "Version": "2012-10-17", "Id": "Policy1676302010732", "Statement": [ { "Sid": "Stmt1676302006390", "Effect": "Allow", "Principal": { "AWS": "AROA6OPZZLYFIE6IYBEF4" }, "Action": "sqs:*", "Resource": "arn:aws:sqs:us-west-2:995556942157:TRUCKDIM.fifo" } ] }
目前应用日志中出现TRUCKDIM.fifo队列的访问拒绝错误,而手动在控制台粘贴角色ARN配置策略则一切正常。请问为何Terraform会将ecs-task-role的ARN替换为角色ID?
原因及解决方法
原因
- AWS API自动转换:当通过Terraform提交包含角色ARN的SQS策略时,AWS SQS API会自动将角色ARN解析为对应的角色ID(AROA开头的字符串)并存储,这是AWS服务内部的标准化处理行为。
- 权限不匹配根源:角色ID本身是有效的身份标识,但出现访问拒绝的核心原因通常是:
- ECS任务角色的信任策略配置错误,导致任务无法正确承担该角色;
- Terraform资源引用错误,导致策略绑定的角色ID并非目标ecs-task-role的身份。
解决方法
- 通过Terraform动态引用角色ARN:避免硬编码角色ARN,直接引用Terraform创建的ecs-task-role资源的ARN属性,确保策略绑定的是正确的角色。修改后的policy部分示例:
policy = jsonencode({ "Version": "2012-10-17", "Id": "Policy1676302010732", "Statement": [ { "Sid": "Stmt1676302006390", "Effect": "Allow", "Principal": { "AWS": aws_iam_role.ecs_task_role.arn }, "Action": "sqs:*", "Resource": aws_sqs_queue.queue_fifo-01.arn } ] })
- 检查角色信任策略:确保ecs-task-role的信任策略允许ECS服务承担该角色,示例配置:
resource "aws_iam_role" "ecs_task_role" { name = "ecs-task-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ecs-tasks.amazonaws.com" } } ] }) }
- 验证角色身份对应关系:通过AWS CLI执行
aws iam get-role --role-name ecs-task-role,查看返回的RoleId,确认控制台中显示的角色ID是否与该值一致,排除角色混淆问题。
内容的提问来源于stack exchange,提问作者mrdoogees
相关产品推荐
相关产品推荐

