Search code examples
terraformterraform-provider-azure

Terraform: Nested for_each in nested dynamic blocks


I have the following variable definition:

variable "rule-configuration" {
  description = "Configuration of the Firewall rules. The key is the name of the rule"
  type = map(object({
    priority           = number
    hub_prefix = string
    spoke_prefixes = list(object({
      name = string
      cidr = string
    }))
  }))
}

I have the following resource definition:

resource "azurerm_firewall_policy_rule_collection_group" "this" {
  name               = "xxx"
  firewall_policy_id = "xxx"
  priority           = 500

  dynamic "network_rule_collection" {
    for_each = var.firewall_configuration

    content {
      name     = each.key
      priority = each.value.priority
      action   = "Allow"

      dynamic "rule" {
        for_each = each.value.spoke_prefixes

        content {
          name                  = ??.value.name
          source_addresses      = [each.value.hub_prefix]
          destination_addresses = [??.value.cidr]
          protocols             = ["Any"]
          destination_ports     = ["*"]
        }
      }
    }
  }
}

How can I make the nested for_each in the nested dynamic block work?


Solution

  • Terraform allows to specify the iterator what allows to use it for a nested for_each:

    resource "azurerm_firewall_policy_rule_collection_group" "this" {
      name               = "xxx"
      firewall_policy_id = "xxx"
      priority           = 500
    
      dynamic "network_rule_collection" {
        for_each = var.firewall_configuration
        iterator = firewall_configuration
    
        content {
          name     = firewall_configuration.key
          priority = firewall_configuration.value.priority
          action   = "Allow"
    
          dynamic "rule" {
            for_each = each.value.spoke_prefixes
            iterator = rule
    
            content {
              name                  = rule.value.name
              source_addresses      = [each.value.hub_prefix]
              destination_addresses = [rule.value.cidr]
              protocols             = ["Any"]
              destination_ports     = ["*"]
            }
          }
        }
      }
    }