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
相关产品推荐
相关产品推荐

