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

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?

原因及解决方法

原因

  1. AWS API自动转换:当通过Terraform提交包含角色ARN的SQS策略时,AWS SQS API会自动将角色ARN解析为对应的角色ID(AROA开头的字符串)并存储,这是AWS服务内部的标准化处理行为。
  2. 权限不匹配根源:角色ID本身是有效的身份标识,但出现访问拒绝的核心原因通常是:
    • ECS任务角色的信任策略配置错误,导致任务无法正确承担该角色;
    • Terraform资源引用错误,导致策略绑定的角色ID并非目标ecs-task-role的身份。

解决方法

  1. 通过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
    }
  ]
})
  1. 检查角色信任策略:确保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"
        }
      }
    ]
  })
}
  1. 验证角色身份对应关系:通过AWS CLI执行aws iam get-role --role-name ecs-task-role,查看返回的RoleId,确认控制台中显示的角色ID是否与该值一致,排除角色混淆问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:31:58