diff --git a/src/modules/role_assignments/built_in_role/_locals.tf b/src/modules/role_assignments/built_in_role/_locals.tf new file mode 100644 index 00000000..d58623ec --- /dev/null +++ b/src/modules/role_assignments/built_in_role/_locals.tf @@ -0,0 +1,35 @@ +locals { + + flat_assignments = flatten([ + for role_definition_name, resources in var.settings : [ + for resource_key, resource_details in resources : [ + for principal_type, principals in try(resource_details, {}) : [ + for principal in( + can(principals) && length(principals) > 0 ? principals : [] + ) : { + role_definition_name = role_definition_name + resource_key = resource_key + resource_type = var.resource_type + principal_type = principal_type + principal = principal + } + ] + ] + ] + ]) + + + users_email = { + for a in local.flat_assignments : + a.principal => a.principal + if a.principal_type == "users_email" + && !can(regex("^[0-9a-fA-F-]{36}$", a.principal)) + } + + + group_names = { + for a in local.flat_assignments : + a.principal => a.principal + if a.principal_type == "group_name" + } +} diff --git a/src/modules/role_assignments/built_in_role/main.tf b/src/modules/role_assignments/built_in_role/main.tf index fc97bf32..2253faba 100644 --- a/src/modules/role_assignments/built_in_role/main.tf +++ b/src/modules/role_assignments/built_in_role/main.tf @@ -1,48 +1,56 @@ resource "azurerm_role_assignment" "main" { for_each = tomap({ - for item in flatten([ - for role_definition_name, resources in var.settings : [ - for resource_key, resource_details in resources : [ - for principal_type, principals in try(resource_details, {}) : [ - for principal in( - # Handle cases where the principal is a list (like object_ids) or a single value - can(principals) && length(principals) > 0 ? principals : [] - ) : { - role_definition_name = role_definition_name - resource_key = resource_key - resource_type = var.resource_type - principal_type = principal_type - principal = principal - } - ] - ] - ] - ]) : - # Ensure unique keys for each role assignment + for item in local.flat_assignments : "${item.role_definition_name}-${item.resource_key}-${item.principal_type}-${item.principal}" => item }) - scope = try(var.resources[ - try(var.settings.lz_key, var.client_config.landingzone_key) - ].virtual_networks[ - split("/", each.value.resource_key)[0] - ].subnets[ - split("/", each.value.resource_key)[1] + scope = try( + var.resources[ + try(var.settings.lz_key, var.client_config.landingzone_key) + ].virtual_networks[ + split("/", each.value.resource_key)[0] + ].subnets[ + split("/", each.value.resource_key)[1] ].id, var.resources[ try(var.settings.lz_key, var.client_config.landingzone_key) ][var.resource_type][each.value.resource_key].id, null ) + principal_id = try( - # If principal is directly an ID (like object_ids), use it. Otherwise, resolve via var.resources. each.value.principal_type == "object_ids" ? each.value.principal + + : each.value.principal_type == "users_email" + ? data.azuread_user.users[each.value.principal].object_id + + : each.value.principal_type == "group_name" + ? data.azuread_group.groups[each.value.principal].object_id + + : var.resources[ - try(var.settings.lz_key, var.client_config.landingzone_key) - ][each.value.principal_type][each.value.principal].principal_id, + can(regex("/", each.value.principal)) + ? split("/", each.value.principal)[0] + : try(var.settings.lz_key, var.client_config.landingzone_key) + ][each.value.principal_type][ + can(regex("/", each.value.principal)) + ? split("/", each.value.principal)[1] + : each.value.principal + ].principal_id, null ) + role_definition_name = each.value.role_definition_name } + +data "azuread_user" "users" { + for_each = local.users_email + user_principal_name = each.value +} + +data "azuread_group" "groups" { + for_each = local.group_names + display_name = each.value +}