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

Terraform AWS跨账号ECR策略多角色Principal嵌套循环问题

Terraform 配置ECR跨账号多角色访问策略实现方案

问题场景

配置ECR仓库跨账号访问策略时,单账号绑定单个角色的授权代码可正常运行,代码如下:

#X-Account Policy for the repositories
data "aws_iam_policy_document" "components_policy" {
  statement {
    sid    = "AllowPushPull"
    effect = "Allow"

    actions = [
      "ecr:BatchCheckLayerAvailability",
      "ecr:BatchGetImage",
      "ecr:CompleteLayerUpload",
      "ecr:GetDownloadUrlForLayer",
      "ecr:InitiateLayerUpload",
      "ecr:PutImage",
      "ecr:UploadLayerPart"
    ]

    principals {
      type = "AWS"
      identifiers = [
        for account_id in var.whitelisting :
          "arn:aws:iam::${account_id}:role/eks-node-role"
      ]
    }
  }
}

当需要为每个白名单账号配置3个授权角色时,使用heredoc拼接ARN的写法无法生效,错误实现代码如下:

#X-Account Policy for the repositories
data "aws_iam_policy_document" "components_policy" {
  statement {
    sid    = "AllowPushPull"
    effect = "Allow"

    actions = [
      "ecr:BatchCheckLayerAvailability",
      "ecr:BatchGetImage",
      "ecr:CompleteLayerUpload",
      "ecr:GetDownloadUrlForLayer",
      "ecr:InitiateLayerUpload",
      "ecr:PutImage",
      "ecr:UploadLayerPart"
    ]

    principals {
      type = "AWS"
      identifiers = [
        for account_id in var.whitelisting :
          <<EOF
                "arn:aws:iam::${account_id}:role/eks-node-role-1",
                "arn:aws:iam::${account_id}:role/eks-node-role-2",
                "arn:aws:iam::${account_id}:role/eks-node-role-3"
            EOF
      ]
    }
  }
}

该写法失效的核心原因:heredoc会将内部的多行内容拼接为单个完整字符串,最终生成的identifiers列表元素是带引号、换行、缩进的大段文本,不是独立的IAM角色ARN,IAM服务无法识别该格式的授权主体。

可行实现方案

不需要使用dynamic块,Terraform原生支持嵌套for循环配合flatten函数生成目标列表,直接修改identifiers部分的逻辑即可,正确代码如下:

#X-Account Policy for the repositories
data "aws_iam_policy_document" "components_policy" {
  statement {
    sid    = "AllowPushPull"
    effect = "Allow"

    actions = [
      "ecr:BatchCheckLayerAvailability",
      "ecr:BatchGetImage",
      "ecr:CompleteLayerUpload",
      "ecr:GetDownloadUrlForLayer",
      "ecr:InitiateLayerUpload",
      "ecr:PutImage",
      "ecr:UploadLayerPart"
    ]

    principals {
      type = "AWS"
      identifiers = flatten([
        for account_id in var.whitelisting : [
          "arn:aws:iam::${account_id}:role/eks-node-role-1",
          "arn:aws:iam::${account_id}:role/eks-node-role-2",
          "arn:aws:iam::${account_id}:role/eks-node-role-3"
        ]
      ])
    }
  }
}

逻辑说明

  • 外层for循环遍历所有白名单账号ID,为每个账号生成包含3个角色ARN的子列表
  • flatten函数会将嵌套的子列表展平为一维字符串列表,完全匹配identifiers参数的格式要求

如果后续需要调整授权角色数量,可将角色名抽为公共变量,通过两层嵌套循环简化维护:

locals {
  # 统一维护所有需要授权的角色名
  allowed_ecr_roles = ["eks-node-role-1", "eks-node-role-2", "eks-node-role-3"]
}

# principals块内identifiers可简化为
identifiers = flatten([
  for account_id in var.whitelisting : [
    for role_name in local.allowed_ecr_roles : "arn:aws:iam::${account_id}:role/${role_name}"
  ]
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:09:14