Home > Back-end >  Terraform loop data source and locals in a single resource
Terraform loop data source and locals in a single resource

Time:09-02

Trying to create Azure role assignments using the below variable

variable "role_assignments" {
  type = map(list(string))
  default = {
    "Contributor" = ["prod-azure-contrib-sbox"],
    "Owner"       = ["gcp-org-cloud-delivery"]
  }
}

flatten the variable

locals {
  groupsbyrole = flatten([
    for roleName, groupList in var.role_assignments : [
      for groupName in groupList : {
        role_name  = roleName
        group_name = groupName
      }
    ]
  ])
  }

The code for creating the role assignments are below

resource "azurerm_role_assignment" "role_assignment" {
    for_each = {
    for group in local.groupsbyrole : "${group.role_name}.${group.group_name}}" => group
    
  }
    scope                            = azurerm_resource_group.az-rg.id
    role_definition_name             = each.value.role_name
    principal_id =  each.value.group_name
    skip_service_principal_aad_check = var.skip_service_principal_aad_check
}

Unfortunately, the principal_id needs to be the object id and not the name which in this case ends up as prod-azure-contrib-sbox or gcp-org-cloud-delivery. Now entry data sources to get the object_id

data "azuread_group" "group" {
 display_name =  either prod-azure-contrib-sbox or gcp-org-cloud-delivery
}

Somehow I need to assign the principal_id in the above resource block with the corresponding azuread_group.group.object_id.

Been trying various ways. One way is to get the data source values into a list to use it in azurerm_role_assignment but it needs two loops and it Terraform doesnt support that. Tried to get the data source inside the resource block and that's not allowed either.

Any other ideas how this can be achieved?

Thanks.

CodePudding user response:

You should be able to use for_each in your data source:

data "azuread_group" "group" {
    for_each = {
         for group in local.groupsbyrole : 
           "${group.role_name}.${group.group_name}" => group
    }

    display_name =   each.value.group_name
}

then

resource "azurerm_role_assignment" "role_assignment" {
    for_each = {
         for group in local.groupsbyrole : 
          "${group.role_name}.${group.group_name}" => group    
    }
    scope                            = azurerm_resource_group.az-rg.id
    role_definition_name             = each.value.role_name
    principal_id                     = data.azuread_group.group[each.key].object_id
    skip_service_principal_aad_check = var.skip_service_principal_aad_check
}
  • Related