Nested loops with terraform

Hello, I have the following data structure, and I have a module that needs to loop over this map:

   webapps = {
w1= {
    site_config = {}
    slots = {
      dev = {
        site_config = {}
      },
      uat-staging = {
        site_config = {
          site_config = {}
        }
      },
      uat-live = {
        site_config = {
          site_config = {}
        }
      },
      production-stage = {
        site_config = {
          site_config = {}
        }
      }
    }
    core_app_service_to_blob_role_assignment = {
      app   = ["container1", "container2"]
      audit = ["container3", "container4"]
    }

  }
      
      }

I call the module with a for_each and for loops which should generate a new map with a key = webapp name (w1) and value = core_app_service_to_blob_role_assignment :

module "role-assignment" {
  providers = {
    azurerm         = azurerm
    azurerm.central = azurerm.central
  }

  for_each = {for k, v in var.webapps : k => { for sa, container in v.core_app_service_to_blob_role_assignment : sa => container }}

  source = "./modules/role-assignment"

  assignments = each.value["app"]
  principle_id = module.app-service-core[each.key].app_service_slot_identity_service_principal_id
}

But getting the following error:

│ Error: Invalid index
│
│   on main.tf line 102, in module "role-assignment":
│  102:   assignments = each.value["app"]
│     ├────────────────
│     │ each.value is object with no attributes
│
│ The given key does not identify an element in this collection value.

Hi @taljundi,

To debug something like this, it can be helpful to temporarily create a smaller separate configuration that focuses only on one part of the problem at a time. In your case, I think I would try to factor out that for_each expression to make sure it has a suitable shape.

For example:

variable "webapps" {
  # (include whatever type constraint your real variable has)
  default = {
    w1 = {
      site_config = {}
      slots = {
        dev = {
          site_config = {}
        },
        uat-staging = {
          site_config = {
            site_config = {}
          }
        },
        uat-live = {
          site_config = {
            site_config = {}
          }
        },
        production-stage = {
          site_config = {
            site_config = {}
          }
        }
      }
      core_app_service_to_blob_role_assignment = {
        app   = ["container1", "container2"]
        audit = ["container3", "container4"]
      }
    }
  }
}

output "result" {
  value = {
    for k, v in var.webapps : k => {
      for sa, container in v.core_app_service_to_blob_role_assignment : sa => container
    }
  }
}

You can then use terraform apply on this smaller configuration to make sure that this result output value produces a suitable value for for_each to use.

One thing I notice on first read is that your nested for expression seems redundant:

{ for sa, container in v.core_app_service_to_blob_role_assignment : sa => container }

This is just mapping the input to the same output, so it would be just the same to write v.core_app_service_to_blob_role_assignment alone here. However, that won’t change the result you are seeing; I suggest it only because making things simpler typically makes debugging easier.