Terraform嵌套for-each实现Azure密钥库RBAC权限配置问题
解决Terraform中嵌套for-each实现Key Vault密钥RBAC权限分配的问题
问题核心
当前代码无法实现需求的原因有两点:
azurerm_role_assignment的principal_id字段要求传入单个AAD对象ID,但直接赋值了each.value.visibility这个列表类型的值- 原
for_each仅遍历服务账号集合,无法处理每个服务账号下visibility列表中的多个用户,需要将嵌套结构扁平化后再遍历
解决方案
通过构造扁平化的本地变量,把每个服务账号与对应的每个授权用户组合成独立条目,再基于这个变量做for_each遍历,实现单个角色分配对应单个用户。
步骤1:构造扁平化的本地变量
在模块中添加以下本地变量定义,将嵌套的visibility列表展开为扁平结构:
locals { flattened_visibility_users = merge([ for user_key, user in var.user_collection : { for principal_id in user.visibility : "${user_key}:${principal_id}" => { user_name = user.name principal_id = principal_id } } ]...) }
该表达式会把每个服务账号的每个visibility用户转换为一个唯一键(格式为服务账号键:AAD对象ID),对应的值包含服务账号名称和单个用户的对象ID,最终生成的结构示例:
{ "user_1:b9ad7db3-ea64-4815-aad5-a5a72b5bbee9" = { user_name = "TEST_SVC_1" principal_id = "b9ad7db3-ea64-4815-aad5-a5a72b5bbee9" } "user_1:d634ebdf-6928-427c-9678-fc3bad8eccc4" = { user_name = "TEST_SVC_1" principal_id = "d634ebdf-6928-427c-9678-fc3bad8eccc4" } }
步骤2:修改角色分配资源代码
使用扁平化后的本地变量作为for_each的遍历对象,同时给principal_id赋值单个用户的对象ID:
# 为指定用户分配Key Vault密钥访问权限 resource "azurerm_role_assignment" "secret_access_provision" { for_each = local.flattened_visibility_users scope = "${module.variables.keyVault-id}/secrets/${replace(each.value.user_name, "_", "-")}" role_definition_name = "Key Vault Secrets User" principal_id = each.value.principal_id }
关键说明
merge([...])...中的三个点是Terraform的扩展运算符,用于将多个map合并为一个顶层map- 唯一键
${user_key}:${principal_id}确保每个角色分配资源都有唯一标识符,避免Terraform出现资源重复错误 - 扁平化后的结构让每个角色分配对应一个独立的服务账号+授权用户组合,完全符合
azurerm_role_assignment的资源要求
内容的提问来源于stack exchange,提问作者Tomas Gryzbon
相关产品推荐
相关产品推荐

