Search code examples
azureloopsterraformterraform-provider-azurehashicorp

Iterate over list inside a map of maps with condition


variable:

gateways:
  gateway1:
    routingConfig:
      sslCertificates: [
        "a",
        "b"
      ],
    ## amended for brievity
  gateway2:
    routingConfig: {}
    ## amended for brievity

code attempt:

data "azurerm_key_vault_secret" "ssl_certificates" {
  for_each = {
    for k, v in local.gateways : v.routing_config.ssl_certificates
    if v.routing_config != {}
  }

  name         = each.value
  key_vault_id = data.azurerm_key_vault.ssl_certificates.id
}

which doesnt work, it only creates a single iteration per gateway and attempts to insert tuple into the name:

each.value is tuple with 2 element

which is expected, if you think about it, but I cant figure out how do I do a loop inside a loop

for the gateway same data structure works, because I can do dynamic for ssl_certificates property, but I dont think I can do that here

final solution:

certificates_flat = merge([
  for gtw, gtw_details in local.gateways : {
    for ssl_cert in gtw_details.routing_config.ssl_certificates :
    ssl_cert => ssl_cert
  } if gtw_details.routing_config != {}
]...)

data "azurerm_key_vault_secret" "ssl_certificates" {
  for_each     = local.certificates_flat
  name         = each.value
  key_vault_id = data.azurerm_key_vault.ssl_certificates.id
}

Solution

  • how do I do a loop inside a loop

    You have to flatten your variable. For example as follows:

    locals {
      gateways_flat = merge([
        for gtw, gtw_details in local.gateways: {
          for ssl_cert in gtw_details.routing_config.ssl_certificates:
            "${gtw}-${ssl_cert}" => {
              ssl_certificate = ssl_cert
            }
        } if gtw_details.routing_config != {}
        
      ]...)
    }
    

    giving:

    {
      "gateway1-a" = {
        "ssl_certificate" = "a"
      }
      "gateway1-b" = {
        "ssl_certificate" = "b"
      }
    }
    

    then

    data "azurerm_key_vault_secret" "ssl_certificates" {
      for_each = local.gateways_flat
      name         = each.value.ssl_certificate
      key_vault_id = data.azurerm_key_vault.ssl_certificates.id
    }