Home > Net >  Error in creating multiple NSGs using single terraform module
Error in creating multiple NSGs using single terraform module

Time:04-25

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 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"
},

CodePudding user response:

I think I understand what you want to do, and this is flattening of your nested variable var.nsgs. If so, you can do the following:

  
locals {
    custom_rules = merge([
            for k,v in var.nsgs: {
                for idx, rules in v.custom_rules:
                    "${k}-${idx}" => merge(rules, {sg_name = k})
             }   
        ]...)
}

which will result in:

custom_rules = {
  "nsg_nm-0" = {
    "access" = "Deny"
    "description" = "Deny all inbound ports"
    "destination_address_prefix" = "*"
    "destination_port_range" = "*"
    "direction" = "Inbound"
    "name" = "DenyAllIn"
    "priority" = 4096
    "protocol" = "tcp"
    "sg_name" = "nsg_nm"
    "source_address_prefix" = "*"
    "source_port_range" = "*"
  }
  "nsg_nm-1" = {
    "access" = "Deny"
    "description" = "Deny all outbound ports"
    "destination_address_prefix" = "*"
    "destination_port_range" = "*"
    "direction" = "Outbound"
    "name" = "DenyAllOut"
    "priority" = 4096
    "protocol" = "tcp"
    "sg_name" = "nsg_nm"
    "source_address_prefix" = "*"
    "source_port_range" = "*"
  }
  "nsg_nv-0" = {
    "access" = "Deny"
    "description" = "Deny all inbound ports"
    "destination_address_prefix" = "*"
    "destination_port_range" = "*"
    "direction" = "Inbound"
    "name" = "DenyAllIn"
    "priority" = 4096
    "protocol" = "tcp"
    "sg_name" = "nsg_nv"
    "source_address_prefix" = "*"
    "source_port_range" = "*"
  }
  "nsg_nv-1" = {
    "access" = "Deny"
    "description" = "Deny all outbound ports"
    "destination_address_prefix" = "*"
    "destination_port_range" = "*"
    "direction" = "Outbound"
    "name" = "DenyAllOut"
    "priority" = 4096
    "protocol" = "tcp"
    "sg_name" = "nsg_nv"
    "source_address_prefix" = "*"
    "source_port_range" = "*"
  }
}
  • Related