Terraform部署Azure角色分配:同一SPID多角色被覆盖问题求助
问题原因
你遇到的问题根源在于Terraform的map类型要求键必须唯一,你定义的subscription_access_list_by_id里,同一个SPID作为键出现了两次,后面的角色值会直接覆盖前面的,最终map里每个SPID只会保留最后一个对应的角色,所以部署后每个服务主体只有最后一个角色生效。
解决方法
不需要过度复杂化配置,只需要调整数据结构,确保每个遍历条目有唯一的键即可,这里提供两种实用方案:
方案1:直接定义带唯一键的map
把原来的map改成每个键是「SPID+角色名」的组合,值包含SPID和角色名,这样每个键都是唯一的,不会被覆盖:
locals { subscription_access_list_by_id = { "SPID########1-reader" = { principal_id = "SPID########1" role_name = "reader" }, "SPID########1-storage-blob-data-reader" = { principal_id = "SPID########1" role_name = "storage blob data reader" }, "SPID########2-owner" = { principal_id = "SPID########2" role_name = "owner" }, "SPID########2-storage-blob-data-owner" = { principal_id = "SPID########2" role_name = "storage blob data owner" } } }
然后修改main.tf里的模块调用:
module "access-control" { for_each = local.subscription_access_list_by_id source = "modules/access-control" principal_id = each.value.principal_id subscription_id = var.subscription_id role_definition_name = each.value.role_name }
方案2:用列表+for表达式生成唯一map
如果觉得手动写唯一键麻烦,可以先定义列表格式的权限配置,再通过for表达式自动生成带唯一键的map:
locals { # 用列表存储所有权限条目,每个条目包含SPID和角色 subscription_access_list = [ { principal_id = "SPID########1", role_name = "reader" }, { principal_id = "SPID########1", role_name = "storage blob data reader" }, { principal_id = "SPID########2", role_name = "owner" }, { principal_id = "SPID########2", role_name = "storage blob data owner" } ] # 自动生成唯一键的map:用SPID+替换空格后的角色名作为键 subscription_access_list_map = { for item in local.subscription_access_list : "${item.principal_id}-${replace(item.role_name, " ", "-")}" => item } }
然后main.tf里调用模块时遍历这个自动生成的map:
module "access-control" { for_each = local.subscription_access_list_map source = "modules/access-control" principal_id = each.value.principal_id subscription_id = var.subscription_id role_definition_name = each.value.role_name }
补充说明
你之前尝试的{for k, v in subscription_access_list_by_id : k => v }没用,是因为原map在定义时已经完成了键的去重和值覆盖,遍历的是已经被修改后的map,自然无法得到所有角色条目。
内容的提问来源于stack exchange,提问作者DevOpsIsNotForMe
相关产品推荐
相关产品推荐

