azureterraformterraform-provider-azurehashicorpterraform-modules

how to write a condition in for_each in terraform


I am trying to create App and Data VMs in two different Availability Sets. But below terraform code creates 4 Availability Sets in associates for each VM.

Can someone throw the light how to configure the App Virtual Machines in 1 App Availability set and Data Virtual Machines in 1Data Availability Set? instead of creating the 4 Availability Sets

parameters.tf

locals {
  rhel= {
    vms = {
      app_vm1 = {
        "vm_name"    = "app"
        "vm_size"    = "Standard_DS2_v2"
        "vm_num"     = "1"
        "publisher"  = "RedHat"
        "offer"      = "RHEL"
        "sku"        = "88-gen2"
        "version"    = "latest"
        "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"      },
      app_vm2 = {
        "vm_name"    = "app"
        "vm_size"    = "Standard_DS2_v2"
        "vm_num"     = "2"
        "publisher"  = "RedHat"
        "offer"      = "RHEL"
        "sku"        = "88-gen2"
        "version"    = "latest"
        "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
      },
      data_vm1 = {
        "vm_name"    = "data"
        "vm_size"    = "Standard_DS2_v2"
        "vm_num"     = "1"
        "publisher"  = "RedHat"
        "offer"      = "RHEL"
        "sku"        = "88-gen2"
        "version"    = "latest"
        "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"      },
      data_vm2 = {
        "vm_name"    = "data"
        "vm_size"    = "Standard_DS2_v2"
        "vm_num"     = "2"
        "publisher"  = "RedHat"
        "offer"      = "RHEL"
        "sku"        = "88-gen2"
        "version"    = "latest"
        "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
      }
    }
  }
}

VirtualMachine.tf

resource "azurerm_availability_set" "as" {
  for_each                                 = module.vms.os.vms
  name                                     = "${each.value.vm_name}-${each.value.vm_num}-as"
  location                                 = data.azurerm_resource_group.rg.location
  resource_group_name                      = data.azurerm_resource_group.rg.name
  platform_fault_domain_count              = 2
  platform_update_domain_count             = 5
  tags                                     = module.vms.env.default_tags
}

resource "azurerm_network_interface" "nic" {
  for_each            = module.vms.os.vms
  name                = "${var.vm_prefix}-${each.value.vm_name}-${each.value.vm_num}-nic"
  location            = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name
  ip_configuration {
    name                          = "my_nic_configuration"
    subnet_id                     = each.value.subnet
    private_ip_address_allocation = "Dynamic"
  }
  tags = module.vms.env.default_tags
}

resource "azurerm_linux_virtual_machine" "vm" {
  for_each                        = module.vms.os.vms
  name                            = "${var.vm_prefix}-${each.value.vm_name}-${each.value.vm_num}"
  admin_username                  = var.admin_username
  admin_password                  = var.admin_password
  disable_password_authentication = false
  location                        = data.azurerm_resource_group.rg.location
  resource_group_name             = data.azurerm_resource_group.rg.name
  network_interface_ids           = [azurerm_network_interface.nic[each.key].id]
  size                            = each.value.vm_size
  availability_set_id             = azurerm_availability_set.as[each.key].id
  identity {
    type = "SystemAssigned"
  }
  os_disk {
    name                 = "${var.vm_prefix}-${each.value.vm_name}-${each.value.vm_num}-OSdisk"
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }
  source_image_reference {
    publisher     = each.value.publisher
    offer         = each.value.offer
    sku           = each.value.sku
    version       = each.value.version
  }

  tags = module.vms.env.default_tags
}

Solution

  • You should be able to use:

    for_each = {for k, vm in local.rhel.vms : k => vm if vm.vm_name == "app"}
    

    and:

    for_each = {for k, vm in local.rhel.vms : k => vm if vm.vm_name == "data"}
    

    That is, if I'm understanding correctly. For example using outputs rather that resources for illustration,

    locals {
      rhel= {
        vms = {
          app_vm1 = {
            "vm_name"    = "app"
              "vm_size"    = "Standard_DS2_v2"
              "vm_num"     = "1"
              "publisher"  = "RedHat"
              "offer"      = "RHEL"
              "sku"        = "88-gen2"
              "version"    = "latest"
              "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"      },
          app_vm2 = {
            "vm_name"    = "app"
              "vm_size"    = "Standard_DS2_v2"
              "vm_num"     = "2"
              "publisher"  = "RedHat"
              "offer"      = "RHEL"
              "sku"        = "88-gen2"
              "version"    = "latest"
              "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
          },
          data_vm1 = {
            "vm_name"    = "data"
              "vm_size"    = "Standard_DS2_v2"
              "vm_num"     = "1"
              "publisher"  = "RedHat"
              "offer"      = "RHEL"
              "sku"        = "88-gen2"
              "version"    = "latest"
              "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"      },
          data_vm2 = {
            "vm_name"    = "data"
              "vm_size"    = "Standard_DS2_v2"
              "vm_num"     = "2"
              "publisher"  = "RedHat"
              "offer"      = "RHEL"
              "sku"        = "88-gen2"
              "version"    = "latest"
              "subnet"     = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
          }
        }
      }
    }
    
    output "app" {
      value = {for k, vm in local.rhel.vms : k => vm if vm.vm_name == "app"}
    }
    
    output "data" {
      value = {for k, vm in local.rhel.vms : k => vm if vm.vm_name == "data"}
    }
    

    Yields:

    Changes to Outputs:
      + app  = {
          + app_vm1 = {
              + offer     = "RHEL"
              + publisher = "RedHat"
              + sku       = "88-gen2"
              + subnet    = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
              + version   = "latest"
              + vm_name   = "app"
              + vm_num    = "1"
              + vm_size   = "Standard_DS2_v2"
            }
          + app_vm2 = {
              + offer     = "RHEL"
              + publisher = "RedHat"
              + sku       = "88-gen2"
              + subnet    = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
              + version   = "latest"
              + vm_name   = "app"
              + vm_num    = "2"
              + vm_size   = "Standard_DS2_v2"
            }
        }
      + data = {
          + data_vm1 = {
              + offer     = "RHEL"
              + publisher = "RedHat"
              + sku       = "88-gen2"
              + subnet    = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
              + version   = "latest"
              + vm_name   = "data"
              + vm_num    = "1"
              + vm_size   = "Standard_DS2_v2"
            }
          + data_vm2 = {
              + offer     = "RHEL"
              + publisher = "RedHat"
              + sku       = "88-gen2"
              + subnet    = "/subscriptions/mysub/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/app"
              + version   = "latest"
              + vm_name   = "data"
              + vm_num    = "2"
              + vm_size   = "Standard_DS2_v2"
            }
        }