skip to Main Content

Please how do I simplify this configuration using locals, the code works fine as is but gets complex passing the variables manually each time.

VARIABLES:

variable "vm_all" {
    type = list(object({}))
    default = [
      {
        name        = "vm1"
        rg  = "rg1"
        sn  = "sn1"
        sn_prefix = ["10.0.1.0/24"]
          },
      {
        name        = "vm2"
        rg  = "rg2"
        sn  = "sn2"
        sn_prefix = ["10.0.2.0/24"]
          },
      {
        name        = "vm3"
        rg  = "rg3"
        sn  = "sn3"
        sn_prefix = ["10.0.3.0/24"]
          }
    ]
    }

CURRENT ITERATION USING LOCALS:(requires manually mapping the variables as shown above)

resource "example_resource" "resource1" {
    for_each     = {for vm_all in var.vm_all:  vm_all.name => vm_all }
    name         = each.value.name
    rg           = each.value.rg
    sn           = each.value.sn
    sn_prefix    = each.value.sn_prefix
}

DESIRED METHOD OF PASSING VARIABLES:

 variable "name" {
    default = [
    "vm1",
    "vm2",
    "vm3"
]
 }

 variable "rg_names" {
    default = [
    "rg1",
    "rg2",
    "rg3"
]
 }

variable "subnets" {
    default = [
    "sn1",
    "sn2",
    "sn3"
]
 }

variable "subnet_prefixes" {
    default = [
    "sn_prefix1",
    "sn_prefix2",
    "sn_prefix3"
]
 }

QUESTION: How can I use locals in a more effective way to allow passing the variables as lists shown above and avoid the need to map manually?

2

Answers


  1. Chosen as BEST ANSWER

    Thank you @Marcin, really helpful but I'm not yet there, I feel so close though, I get the following error when I try to created nics using ids from the created subnets:

    (The given key does not identify an element in this collection value.)

     Error: Invalid index
    │
    │   on main.tf line 165, in resource "azurerm_network_interface" "nic":
    │  165:     subnet_id                     = azurerm_subnet.subnet[each.value.sn].id
    │     ├────────────────
    │     │ azurerm_subnet.subnet is object with 10 attributes
    │     │ each.value.sn is "subnet7"
    │
    │ The given key does not identify an element in this collection value.
    

    see the main.tf below:

    resource "azurerm_subnet" "subnet" {
      for_each             = local.vm_all
      name                 = each.value.sn
      resource_group_name  = each.value.rg
      virtual_network_name = azurerm_virtual_network.vnet.name
      address_prefixes     = each.value.sn_prefix
    }
        
    resource "azurerm_network_interface" "nic" {
          for_each            = local.vm_all
          name                = each.value.name
          location            = var.location
          resource_group_name = each.value.rg
        
          ip_configuration {
            name                          = "internal"
            subnet_id                     = azurerm_subnet.subnet[each.value.sn].id
            private_ip_address_allocation = "Dynamic"
          }
        }
    

  2. You can combine them as follows:

    locals {
      vm_all = {for idx, name in var.name: 
                name => {
                  "name" = name
                  rg  = var.rg_names[idx]
                  sn  = var.subnets[idx]
                  sn_prefix = [var.subnet_prefixes[idx]]
                }
               }
    }
    

    then

    resource "example_resource" "resource1" {
        for_each     = local.vm_all
        name         = each.value.name
        rg           = each.value.rg
        sn           = each.value.sn
        sn_prefix    = each.value.sn_prefix
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search