Error in creating multiple NSGs using single terraform module

I have created a terraform module for creating multiple NSGs. I am getting the below error while implementing it.

main.tf

data "azurerm_resource_group" "rg" {
  name = var.resource_group_name
}

resource "azurerm_network_security_group" "nsg" {
  for_each            = var.nsgs
  name                = each.key
  resource_group_name = data.azurerm_resource_group.rg.name
  location            = data.azurerm_resource_group.rg.location
}



resource "azurerm_network_security_rule" "custom_rules" {
  for_each = local.custom_rules

  name                                       = each.value.name
  priority                                   = each.value.priority
  direction                                  = each.value.direction
  access                                     = each.value.access
  protocol                                   = each.value.protocol
  source_port_ranges                         = each.value.source_port_ranges
  destination_port_ranges                    = each.value.destination_port_ranges
  description                                = each.value.description
  source_address_prefix                      = each.value.source_address_prefix
  source_address_prefixes                    = each.value.source_address_prefixes
  destination_address_prefix                 = each.value.destination_address_prefix
  destination_address_prefixes               = each.value.destination_address_prefixes
  resource_group_name                        = data.azurerm_resource_group.rg.name
  network_security_group_name                = azurerm_network_security_group.nsg.name
  source_application_security_group_ids      = each.value.source_application_security_group_ids
  destination_application_security_group_ids = each.value.destination_application_security_group_ids
}

locals.tf

locals {
  nsgs1 = {
  for_each = var.nsgs 
  custom_rules1 = each.value.custom_rules
}

  custom_rules = {
    for r in local.custom_rules1 :
    r.name => {
      name                                       = r.name
      priority                                   = lookup(r, "priority")
      direction                                  = lookup(r, "direction", "Any")
      access                                     = lookup(r, "access", "Allow")
      protocol                                   = lookup(r, "protocol", "*")
      source_port_ranges                         = split(",", replace(lookup(r, "source_port_range", "*"), "*", "0-65535"))
      destination_port_ranges                    = split(",", replace(lookup(r, "destination_port_range", "*"), "*", "0-65535"))
      source_address_prefix                      = lookup(r, "source_application_security_group_ids", null) == null && lookup(r, "source_address_prefixes", null) == null ? lookup(r, "source_address_prefix", "*") : null
      source_address_prefixes                    = lookup(r, "source_application_security_group_ids", null) == null ? lookup(r, "source_address_prefixes", null) : null
      destination_address_prefix                 = lookup(r, "destination_application_security_group_ids", null) == null && lookup(r, "destination_address_prefixes", null) == null ? lookup(r, "destination_address_prefix", "*") : null
      destination_address_prefixes               = lookup(r, "destination_application_security_group_ids", null) == null ? lookup(r, "destination_address_prefixes", null) : null
      description                                = lookup(r, "description", "Security rule for ${lookup(r, "name", "default_rule_name")}")
      resource_group_name                        = data.azurerm_resource_group.rg.name
      network_security_group_name                = azurerm_network_security_group.nsg.name
      source_application_security_group_ids      = lookup(r, "source_application_security_group_ids", null)
      destination_application_security_group_ids = lookup(r, "destination_application_security_group_ids", null)
    }
  }
}

variables.tf

variable "resource_group_name" {
  description = The name of the resource group in which to create the network security group.
  type        = string
}


variable "nsgs"{
  type = map(object({
    custom_rules = any
  }))
  default = {
    nsg_nm = {
      custom_rules =[      {
      name                   = "DenyAllIn"
      priority               = 4096
      direction              = "Inbound"
      access                 = "Deny"
      protocol               = "tcp"
      source_port_range      = "*"
      destination_port_range = "*"
      source_address_prefix  = "*"
      destination_address_prefix = "*"
      description            = "Deny all inbound ports"
    },
    {
     name                   = "DenyAllOut"
      priority               = 4096
      direction              = "Outbound"
      access                 = "Deny"
      protocol               = "tcp"
      source_port_range      = "*"
      destination_port_range = "*"
      source_address_prefix  = "*"
      destination_address_prefix = "*"
      description            = "Deny all outbound ports"
    },
    ]
    },
        nsg_nv = {
      custom_rules =[      {
      name                   = "DenyAllIn"
      priority               = 4096
      direction              = "Inbound"
      access                 = "Deny"
      protocol               = "tcp"
      source_port_range      = "*"
      destination_port_range = "*"
      source_address_prefix  = "*"
      destination_address_prefix = "*"
      description            = "Deny all inbound ports"
    },
    {
     name                   = "DenyAllOut"
      priority               = 4096
      direction              = "Outbound"
      access                 = "Deny"
      protocol               = "tcp"
      source_port_range      = "*"
      destination_port_range = "*"
      source_address_prefix  = "*"
      destination_address_prefix = "*"
      description            = "Deny all outbound ports"
    },
    ]
    }

    }
  }

The error when I am getting when I am calling this module is shown as below:

Error: each.value cannot be used in this context │ │ on main.tf line 24, in locals: │ 24: custom_rules1 = each.value.custom_rules │ │ A reference to “each.value” has been used in a context in which it is unavailable, such as when the configuration no longer │ contains the value in its “for_each” expression. Remove this reference to each.value in your configuration to work
│ around this error.

Code for calling this module is as below:

resource "azurerm_resource_group" "rg2" {
  name     = "rg2"
  location = "Australia East"
}


module "nsgs" {
   source = "./multiplensgs"
   resource_group_name = azurerm_resource_group.rg2.name
 }

The rules should be shown like this for different nsgs nsg_nm and nsg_nv for below:

{
  name                   = "DenyAllIn"
  priority               = 4096
  direction              = "Inbound"
  access                 = "Deny"
  protocol               = "tcp"
  source_port_range      = "*"
  destination_port_range = "*"
  source_address_prefix  = "*"
  destination_address_prefix = "*"
  description            = "Deny all inbound ports"
},
{
 name                   = "DenyAllOut"
  priority               = 4096
  direction              = "Outbound"
  access                 = "Deny"
  protocol               = "tcp"
  source_port_range      = "*"
  destination_port_range = "*"
  source_address_prefix  = "*"
  destination_address_prefix = "*"
  description            = "Deny all outbound ports"
},

Leave a Comment