'Need to pass values for nsg rules in terraform resource block from a map type variable

I am trying a create a resource block for azurerm_network_security_rule such that it can be mapped with subnet variable being used in resource block as well so that subnet association with nsg would be easy.

for eg. variable is like

variable "subnets" {
  description = "A list of subnets inside the VPC"
  type        = map(any)
  default = {
    subnet = {
      name           = "test"
      address_prefix = ["x.x.x.x/x"]
      attached_nat   = "false"
      inbound_rules = [
        # [name, priority, direction, access, protocol, destination_port_range, source_address_prefix, destination_address_prefix]
        ["http", "100", "Inbound", "Allow", "Tcp", "80", "*", "0.0.0.0/0"],
      ]
      outbound_rules = [
        # [name, priority, direction, access, protocol, destination_port_range, source_address_prefix, destination_address_prefix]
        ["ntp_out", "103", "Outbound", "Allow", "Udp", "123", "", "0.0.0.0/0"],
      ]
    }
 }
}

Getting error

**Error: Invalid for_each argument
│
│   on main.tf line 120, in resource "azurerm_network_security_rule" "subnet":
│  120:    for_each = concat([for k, v in var.subnets: {"inbound_rules"=lookup(v,"inbound_rules",[])}], [for k, v in var.subnets: {"outbound_rules"=lookup(v,"outbound_rules",[])}])
│     ├────────────────
│     │ var.subnets is map of object with 1 element
│
│ The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of strings, and you have provided a value of type │ tuple.╵**

my resource block is like -

resource "azurerm_network_security_group" "subnet" {
  for_each = var.subnets

  name                = format("%s-${each.value.name}")
  location            = var.location
  resource_group_name = var.resource_group_name  
}

resource "azurerm_network_security_rule" "subnet" {
   for_each = concat([for k, v in var.subnets: {"inbound_rules"=lookup(v,"inbound_rules",[])}], [for k, v in var.subnets: {"outbound_rules"=lookup(v,"outbound_rules",[])}])
  name                       = each.value[0]
  priority                   = each.value[1]
  direction                  = each.value[2] 
  access                     = each.value[3] 
  protocol                   = each.value[4] 
  source_port_range          = "*"
  destination_port_range     = each.value[5] 
  source_address_prefix      = each.value[6]
  destination_address_prefix = each.value[7] 
  description                = "${each.value[2]}_Port_${each.value[5]}"
  resource_group_name        = var.resource_group_name
  network_security_group_name = azurerm_network_security_group.subnet[each.key].name
}

If someone can help figuring out the loop to put in for_each to achieve it.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source