Home > Net >  How to pass values from one's module list to another module with for_each
How to pass values from one's module list to another module with for_each

Time:09-21

I have a module that creates vnets and subnets (module vnet):

resource "azurerm_virtual_network" "xxx" {
  count               = length(var.vnets)
  name                = var.vnets[count.index].vnet_name
  address_space       = var.vnets[count.index].address_space
  location            = var.resource_location
  resource_group_name = var.resource_group_name

  dynamic "subnet" {
    for_each = var.vnets[count.index].subnets

    content {
      name           = subnet.value.name
      address_prefix = subnet.value.address
      security_group = azurerm_network_security_group.xxx.id
    }
  }

  tags = var.tags

}

var.vnets is

vnets = [
  {
    vnet_name     = "01-vnet"
    address_space = ["10.0.0.0/23"]
    subnets = [
      {
        name    = "workloads-01"
        address = "10.0.0.0/24"
      }
    ]
  },
  {
    vnet_name     = "02-vnet"
    address_space = ["10.0.2.0/23"]
    subnets = [
      {
        name    = "workloads-02"
        address = "10.0.2.0/24"
      }
    ]
  }
]

And then I pass subnets to my root file

output "subnets" {
  value = flatten(azurerm_virtual_network.xxx[*].subnet[*].id)

}

Resulted output

Outputs:

subnets = [
  "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/virtualNetworks/eis-01-vnet/subnets/eis-workloads-01",
  "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/virtualNetworks/eis-02-vnet/subnets/eis-workloads-02",
]

Now I want to use those subnets when I create VMs in another module (vm module):

resource "azurerm_network_interface" "nics" {
  for_each            = var.vms
  name                = "${each.value.name}-nic"
  location            = var.resource_location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = "iface-${each.value.name}"
    subnet_id                     = element(var.subnet_id, count.index)
    private_ip_address_allocation = "Dynamic"
  }

  tags = var.tags

}

Where var.vms

vms = {
  vm1 = {
    name      = "vm1"
    vm_size   = "Standard_B1ms"
    username  = "centos"
    password  = "222!"
    disk_size = "30"
    sku       = "7_9"
    ext_ip    = "1"
  },
  vm2 = {
    name      = "vm2"
    vm_size   = "Standard_B1ls"
    username  = "centos"
    password  = "111!"
    disk_size = "35"
    sku       = "7_9"
    ext_ip    = ""
  }
}

And var.subnet_id is just, defined in vm module.

variable "subnet_id" {}

My root's main.tf

module "vm" {
  source = "./modules/vm"
  for_each = var.vms

  vms                 = var.vms
  publicip_name       = var.publicip_name
  subnet_id           = module.vnet.subnets[*]
  resource_group_name = azurerm_resource_group.xxx.name
  resource_location   = azurerm_resource_group.xxx.location

  tags = local.common_tags
}

How can I pass subnet_ids from module vnet to module vm, so the resource "azurerm_network_interface" will use one subnet_ids for each key defined in vms?

I would use "element(var.subnet_id, count.index)" for the count, but how can I pass those subnet ids for a resource that will be created with for_each?

CodePudding user response:

You can get iterate over your var.vms with index as follows:

resource "azurerm_network_interface" "nics" {
  for_each            = {for idx, vm in keys(var.vms): idx => var.vms[vm]}
  name                = "${each.value.name}-nic"
  location            = var.resource_location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = "eis-iface-${each.value.name}"
    subnet_id                     = element(var.subnet_id, each.key)
    private_ip_address_allocation = "Dynamic"
  }

  tags = var.tags

}

Note: keys returns the map keys in alphabetical order if that meters.

  • Related