如何修改Terraform的aws_iam_policy_document返回的JSON策略并引用
Terraform实现IAM策略字符串替换的最优方案
不需要额外工具,使用Terraform内置函数即可完成需求,两种适配不同场景的方案如下:
方案1:replace链式子串替换(当前场景最优)
你当前的需求是固定子串替换,直接链式调用两次内置replace函数处理JSON字符串即可,代码最简洁,输出可直接被其他资源引用:
locals { modified_assume_role_policy = replace( replace(data.aws_iam_policy_document.cluster_assume_role_policy.json, ":aud", ":sub"), "sts.amazonaws.com", "system:serviceaccount:kube-system:cluster-autoscaler" ) }
使用说明:
- 内层
replace优先替换所有:aud子串为:sub - 外层
replace再替换所有sts.amazonaws.com为目标ServiceAccount值 - 生成的
local.modified_assume_role_policy是合法JSON字符串,可直接赋值给IAM角色的assume_role_policy等参数使用
方案2:结构化修改(适配策略结构可变场景)
如果担心子串替换匹配到非预期内容,可以先把JSON解析为Terraform对象,修改对应字段后再转回JSON,容错性更高:
locals { # 解析原始JSON为Terraform可操作的对象结构 original_policy = jsondecode(data.aws_iam_policy_document.cluster_assume_role_policy.json) # 提取OIDC提供商信息,避免硬编码 oidc_provider_arn = original_policy.Statement[0].Principal.Federated oidc_provider_id = replace(oidc_provider_arn, "arn:aws:iam::[0-9]+:oidc-provider/", "") # 构造修改后的策略结构 modified_policy = merge( original_policy, { Statement = [ merge( original_policy.Statement[0], { Condition = { StringEquals = { "${oidc_provider_id}:sub" = "system:serviceaccount:kube-system:cluster-autoscaler" } } } ) ] } ) # 转回JSON字符串供其他资源引用 modified_assume_role_policy = jsonencode(local.modified_policy) }
内容的提问来源于stack exchange,提问作者Viji
相关产品推荐
相关产品推荐

