如何用Terraform复用代码块创建多个Azure PIM角色分配
Terraform Azure PIM角色分配代码优化
需求说明
当前在Azure环境中,为不同默认角色(如Data Factory Contributor、Grafana Editor)创建PIM活动角色分配时,每个角色都需要单独编写变量块和资源块,存在大量重复代码。需要将代码压缩为单个资源块,简化维护,同时保持实现简洁。
现有代码
// azurerm_role_definition code block data "azurerm_role_definition" "roles" { for_each = toset(["Data Factory Contributor", "Grafana Editor"]) name = each.value } variable "groupids_data_factory_contributor" { type = list(string) default = ["387400af-3a87-4ee6-ac9b-487283203ecb", "d5ad0c72-5c44-422a-bd2f-7261a1415ed1"] } variable "groupids_grafana_editor" { type = list(string) default = ["387400af-3a87-4ee6-ac9b-487283203ecb", "875a79c6-26dc-4402-a9f4-7a18e3fbde0e"] } resource "azurerm_pim_active_role_assignment" "data_factory_contributor" { for_each = toset(var.groupids_data_factory_contributor) scope = data.azurerm_subscription.primary.id role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.roles["Data Factory Contributor"].id}" principal_id = each.value schedule { start_date_time = time_static.example.rfc3339 expiration { duration_hours = 8 } } ticket { number = "1" system = "blank" } justification = "Expiration Duration Set" } resource "azurerm_pim_active_role_assignment" "grafana_editor" { for_each = toset(var.groupids_grafana_editor) scope = data.azurerm_subscription.primary.id role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.roles["Grafana Editor"].id}" principal_id = each.value schedule { start_date_time = time_static.example.rfc3339 expiration { duration_hours = 8 } } ticket { number = "1" system = "blank" } justification = "Expiration Duration Set" }
优化方案
1. 合并变量定义
将多个分散的groupids_xxx变量合并为一个映射类型变量,键为角色名称,值为对应主体ID列表,统一管理角色与主体的关联关系:
variable "role_principals" { type = map(list(string)) default = { "Data Factory Contributor" = ["387400af-3a87-4ee6-ac9b-487283203ecb", "d5ad0c72-5c44-422a-bd2f-7261a1415ed1"] "Grafana Editor" = ["387400af-3a87-4ee6-ac9b-487283203ecb", "875a79c6-26dc-4402-a9f4-7a18e3fbde0e"] } }
2. 单个资源块实现批量分配
使用嵌套循环将角色与主体的二维组合展开为一维集合,配合for_each遍历所有需要创建的角色分配,彻底消除重复代码:
// 保持原角色定义数据块不变,自动遍历变量中的所有角色 data "azurerm_role_definition" "roles" { for_each = toset(keys(var.role_principals)) name = each.value } // 单个资源块创建所有PIM活动角色分配 resource "azurerm_pim_active_role_assignment" "all_roles" { for_each = { for role_name, principals in var.role_principals : "${role_name}_${principal_id}" => { role_name = role_name principal_id = principal_id } for principal_id in principals } scope = data.azurerm_subscription.primary.id role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.roles[each.value.role_name].id}" principal_id = each.value.principal_id schedule { start_date_time = time_static.example.rfc3339 expiration { duration_hours = 8 } } ticket { number = "1" system = "blank" } justification = "Expiration Duration Set" }
关键说明
for_each中的嵌套循环:遍历每个角色及其对应的主体列表,生成角色名称_主体ID格式的唯一键,确保每个资源实例不重复。- 动态角色关联:通过
each.value.role_name直接匹配数据块中的角色定义,无需硬编码角色名称。 - 扩展性:后续新增角色时,只需在
role_principals变量中添加新的键值对,无需修改资源块代码。
适配合格类型角色分配
如果需要同时创建合格类型的PIM角色分配,只需复制上述资源块,将资源类型改为azurerm_pim_eligible_role_assignment,并根据需求调整参数(比如设置更长的有效期)即可。
内容的提问来源于stack exchange,提问作者ankur kapoor
相关产品推荐
相关产品推荐

