azureterraformazure-availability-set

Terraform Azure creating vm in multiple availability set


I am trying to create multiple Azure VM and not able to assign VMs to different availability_set. Please see my code below:

Module "vm_dev":

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "2.82.0"
    }
  }
}
    
provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg_dev" {
  name     = "MYORG_RG_DEV"
  location = var.location
}
  
resource "azurerm_network_interface" "node_master" {
  for_each = var.instances_master
    
  name                    = "${var.hostname_prefix}-${each.key}-nic"
  resource_group_name     = azurerm_resource_group.rg_dev.name
  location                = azurerm_resource_group.rg_dev.location
  internal_dns_name_label = "${var.hostname_prefix}-${each.key}"
  
  ip_configuration {
    name                          = "primary"
    primary                       = true
    subnet_id                     = var.subnet_id
    private_ip_address            = each.value.ip
    private_ip_address_allocation = "Static"
    private_ip_address_version    = "IPv4"
  }
}

resource "azurerm_linux_virtual_machine" "node_master" {
  for_each = var.instances_master

  name          = "${var.hostname_prefix}-${each.key}"
  computer_name = "${var.hostname_prefix}-${each.key}"
  size          = var.vm_size

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  
  network_interface_ids = [azurerm_network_interface.node_master[each.key].id]

  os_disk {
    name                 = "${var.hostname_prefix}-${each.key}-disk-os"
    storage_account_type = "StandardSSD_LRS"
    caching              = "ReadWrite"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  admin_username = "myuser"
  admin_ssh_key {
    username   = "myuser"
    public_key = file("id.pub")
  }

  disable_password_authentication = true
}

resource "azurerm_network_interface" "node_data" {
  for_each = var.instances_data

  name                    = "${var.hostname_prefix}-${each.key}-nic"
  resource_group_name     = azurerm_resource_group.rg_dev.name
  location                = azurerm_resource_group.rg_dev.location
  internal_dns_name_label = "${var.hostname_prefix}-${each.key}"

  ip_configuration {
    name                          = "primary"
    primary                       = true
    subnet_id                     = var.subnet_id
    private_ip_address            = each.value.ip
    private_ip_address_allocation = "Static"
    private_ip_address_version    = "IPv4"
  }
}

resource "azurerm_linux_virtual_machine" "node_data" {
  for_each = var.instances_data

  name          = "${var.hostname_prefix}-${each.key}"
  computer_name = "${var.hostname_prefix}-${each.key}"
  size          = var.vm_size

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  
  network_interface_ids = [azurerm_network_interface.node_data[each.key].id]

  os_disk {
    name                 = "${var.hostname_prefix}-${each.key}-disk-os"
    storage_account_type = "StandardSSD_LRS"
    caching              = "ReadWrite"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  admin_username = "myuser"
  admin_ssh_key {
    username   = "myuser"
    public_key = file("id.pub")
  }

  disable_password_authentication = true
}

vm.tf:

module "vm_dev" {
  source = "./vm_dev"

  vm_size           = "Standard_D4s_v3"
  hostname_prefix   = "myorg"
  group_name_prefix = var.group_prefix
  location          = var.location
  subnet_id         = local.subnet_id
  ssh_key           = local.ssh_public_key

  instances_master = {
    "aa-elastic-master-0" = { ip = "10.0.100.1" }
    "aa-elastic-master-1" = { ip = "10.0.100.2" }

    "xx-elastic-master-0" = { ip = "10.0.99.1" }
    "xx-elastic-master-1" = { ip = "10.0.99.2" }
  }

  instances_data = {
    "aa-elastic-data-0" = { ip = "10.0.100.3" }
    "aa-elastic-data-1" = { ip = "10.0.100.4" }
    "aa-elastic-data-2" = { ip = "10.0.100.5" }

    "xx-elastic-data-0" = { ip = "10.0.99.3" }
    "xx-elastic-data-1" = { ip = "10.0.99.4" }
    "xx-elastic-data-2" = { ip = "10.0.99.5" }

  }
}

This works fine and I am able to create VMs. So far each VM is being created without assigning to availability_set. I would like to specify to which availability_set each VM belongs to, something like this:

  instances_master = {
    "aa-elastic-master-0" = { ip = "10.0.100.1", as = "azurerm_availability_set.as_aamaster.id" }
    "aa-elastic-master-1" = { ip = "10.0.100.2", as = "azurerm_availability_set.as_aamaster.id" }

    "xx-elastic-master-0" = { ip = "10.0.99.1", as = "azurerm_availability_set.as_xxmaster.id" }
    "xx-elastic-master-1" = { ip = "10.0.99.2", as = "azurerm_availability_set.as_xxmaster.id" }
  }

  instances_data = {
    "aa-elastic-data-0" = { ip = "10.0.100.3", as = "azurerm_availability_set.as_aadata.id" }
    "aa-elastic-data-1" = { ip = "10.0.100.4", as = "azurerm_availability_set.as_aadata.id" }
    "aa-elastic-data-2" = { ip = "10.0.100.5", as = "azurerm_availability_set.as_aadata.id" }

    "xx-elastic-data-0" = { ip = "10.0.99.3", as = "azurerm_availability_set.as_xxdata.id" }
    "xx-elastic-data-1" = { ip = "10.0.99.4", as = "azurerm_availability_set.as_xxdata.id" }
    "xx-elastic-data-2" = { ip = "10.0.99.5", as = "azurerm_availability_set.as_xxdata.id" }

  }

adding in module following code:

resource "azurerm_availability_set" "as_aamaster" {
  name                = "${var.hostname_prefix}-as-aamaster"
  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  managed             = true
}


resource "azurerm_linux_virtual_machine" "node_master" {
  for_each = var.instances_master

  name          = "${var.hostname_prefix}-${each.key}"
  computer_name = "${var.hostname_prefix}-${each.key}"
  size          = var.vm_size

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location

  availability_set_id   = each.value.as
  network_interface_ids = [azurerm_network_interface.node_master[each.key].id]
...

gives me error

Error: Cannot parse Azure ID: parse "azurerm_availability_set.as_aamaster.id": invalid URI for request

  on vm_dev/main.tf line 72, in resource "azurerm_linux_virtual_machine" "node_master":
  72:   availability_set_id   = each.value.as

Any advice is appreciated.

Thanks


Solution

  • AnsumanBal-MT, this did not work for me, I have added comment above, but i was able to solve this via:

    "aa-elastic-master-0" = { ip = "10.0.2.1", as = "0" } 
    "xx-elastic-master-0" = { ip = "10.0.2.3", as = "1" }
    

    in module:

    resource "azurerm_availability_set" "as_dev" {
      count               = 5
      name                = "${var.hostname_prefix}-dev-${element(var.availability_set_name, count.index)}-as"
      resource_group_name = azurerm_resource_group.rg_dev.name
      location            = var.location
    }
    

    for azurerm_linux_virtual_machine added:

    availability_set_id   = azurerm_availability_set.as_dev[each.value.as].id
    

    variable:

    variable "availability_set_name" {
      description = "Availability set name that the VMs will be created in"
      type        = list(any)
      default     = ["aamaster", "xxmaster", "aadata", ....]
    }