Terraform aws_iam_policy_document语句兼容双变量控制及列表遍历实现
解决方案
步骤1:定义兼容两种变量的本地值
先通过本地值统一处理单个serviceaccount字符串和serviceaccounts列表,确保向后兼容:
locals { # 优先使用serviceaccounts列表;若列表为空,检查单个serviceaccount字符串是否非空,非空则转为单元素列表;两者都空则返回空列表 target_serviceaccounts = length(var.serviceaccounts) > 0 ? var.serviceaccounts : (var.serviceaccount != "" ? [var.serviceaccount] : []) }
步骤2:使用Dynamic Block生成Statement
利用Terraform的dynamic块,仅在目标service account列表非空时生成对应的Statement,同时遍历列表生成所有values项:
data "aws_iam_policy_document" "example" { dynamic "statement" { # 仅当target_serviceaccounts非空时,生成一个Statement块 for_each = local.target_serviceaccounts != [] ? [1] : [] content { actions = ["sts:AssumeRole"] principals { type = "Federated" identifiers = [local.eks_oidc_provider_arn] } condition { test = "StringEquals" variable = "${local.eks_oidc_issuer_url}:sub" # 遍历目标service account列表,生成对应的sub值 values = [for sa in local.target_serviceaccounts : "system:serviceaccount:${var.namespace}:${sa}"] } condition { test = "StringEquals" variable = "${local.eks_oidc_issuer_url}:aud" values = ["sts.amazonaws.com"] } } } }
逻辑说明
- 向后兼容:保留了原有的
serviceaccount字符串变量支持,当用户未传入serviceaccounts列表时,会自动将单个service account转为单元素列表处理。 - 跳过Statement:当
serviceaccounts列表为空且serviceaccount字符串为空时,local.target_serviceaccounts为空,dynamic块不会生成任何Statement。 - 多service account支持:当
serviceaccounts列表有多个元素时,values会自动生成对应数量的条目,无需手动编写多个condition块。
内容的提问来源于stack exchange,提问作者opti2k4
相关产品推荐
相关产品推荐

