Terraform中如何通过list变量值获取aws_iam_policy资源的arn属性
问题原因
你注释行的写法本质是拼接普通字符串,Terraform不会将这类动态生成的字符串解析为资源引用,因此无法获取到对应IAM策略的实际ARN值,这种需求在Terraform中完全可以实现,解决方案如下:
实现步骤
1. 构建IAM策略名称到ARN的映射
你可以通过局部值提前将所有已定义的IAM策略资源按名称做索引映射,后续直接通过名称就能取到对应ARN:
locals { # 键为策略名称,值为对应策略的ARN,新增策略时同步更新该映射即可 iam_policy_arn_map = { "dev-policy1" = aws_iam_policy.dev-policy1.arn "dev-policy2" = aws_iam_policy.dev-policy2.arn "qa-policy1" = aws_iam_policy.qa-policy1.arn "qa-policy2" = aws_iam_policy.qa-policy2.arn } }
优化建议:如果策略数量较多,建议直接用
for_each批量创建所有IAM策略,不需要手动维护上述映射:# 先定义所有策略的配置变量 variable "iam_policies" { type = map(object({ name_prefix = string description = string policy = string })) } # 批量创建IAM策略 resource "aws_iam_policy" "all" { for_each = var.iam_policies name_prefix = each.value.name_prefix description = each.value.description policy = each.value.policy } # 此时aws_iam_policy.all天然就是策略名称到资源的映射,无需额外定义local值
2. 修正模块中role_policy_arns的取值逻辑
直接从上述映射中根据变量传入的策略名称取ARN即可:
module "iam_assumable_role" { for_each = var.service_accounts source = "../../../../../../modules/iam-assumable-role-with-oidc/" create_role = true role_name = each.value.name provider_url = replace(module.eks.cluster_oidc_issuer_url, "https://", "") # 修正后的ARN取值逻辑 role_policy_arns = [for policy_name in each.value.policies : local.iam_policy_arn_map[policy_name]] # 如果用了for_each批量创建策略,这里改为 role_policy_arns = [for policy_name in each.value.policies : aws_iam_policy.all[policy_name].arn] oidc_fully_qualified_subjects = each.value.wildcard == "" ? ["system:serviceaccount:${each.value.namespace}:${each.value.name}"] : [] oidc_subjects_with_wildcards = each.value.wildcard != "" ? ["system:serviceaccount:${each.value.namespace}:${each.value.wildcard}"] : [] tags = var.tags }
内容的提问来源于stack exchange,提问作者Ahnenerbe
相关产品推荐
相关产品推荐

