0
votes

I have a requirement where I need to create multiple Azure Windows VMs, with multiple disks each with different sizes and for each VM to be be placed in a different AZ (so if I pass in 3 vm names each one will go to a different AZ along with the disks).

I have got something working with disks of the same size but not when I need to assign disks of different sizes.

Thanks in advance for any help.

Code I have so far:

variable "instances" {
    description = "No. of instances"
    type = list(string)
    default = ["vm-1", "vm-2"]
}


variable "nb_disks_per_instance" {
    description = "No. disks per vm"
    type = number
    default = 2
    
}

variable "disks" {
    description = "disk sizes"
    type = list(number)
    default = [10, 20, 30]
}

locals {

  vm_datadiskdisk_count_map = { for k in toset(var.instances) : k => var.nb_disks_per_instance }
  luns                      = { for k in local.datadisk_lun_map : k.datadisk_name => k.lun }

  datadisk_lun_map = flatten([
    for vm_name, count in local.vm_datadiskdisk_count_map : [
      for i in range(count) : {
        datadisk_name = format("%s_Data_Disk_%02d", vm_name, i)
        lun           = i
      }
    ]
  ])

}

output "myMap" {
  value = local.datadisk_lun_map
}
 
resource "azurerm_managed_disk" "managed_disk" {
  for_each             = toset([for j in local.datadisk_lun_map : j.datadisk_name])
  name                 = replace(each.key, "_", "-")
  location             = "UK South"
  resource_group_name  = "rg-one"
  storage_account_type = "Standard_LRS"
  create_option        = "Empty"
  disk_size_gb         = 20
  tags                 = local.common_tags
  zones                = ["1"] 

}

resource "azurerm_virtual_machine_data_disk_attachment" "managed_disk_attach" {
  for_each           = toset([for j in local.datadisk_lun_map : j.datadisk_name])
  managed_disk_id    = azurerm_managed_disk.managed_disk[each.key].id
  virtual_machine_id = azurerm_windows_virtual_machine.vm[element(split("_", each.key), 0)].id
  lun                = lookup(local.luns, each.key)
  caching            = "ReadWrite"
}

resource "azurerm_network_interface" "nic" {
  for_each            = toset(var.instances)
  location            = "UK South"
  name                = "${each.key}-NIC"
  resource_group_name = "rg-one"
  ip_configuration {
    name                          = "internal"
    private_ip_address_allocation = "Dynamic"
    subnet_id                     = data.azurerm_subnet.subnet.id
  } 
  tags = local.common_tags

}

resource "azurerm_windows_virtual_machine" "vm" {
  for_each       = toset(var.instances)
  admin_password = <ENTER PW>
  admin_username = "test"
  location = "UK South"
  name = each.key
  network_interface_ids = [azurerm_network_interface.nic[format("%s", each.key)].id]
  resource_group_name = "rg-one"
  size = "Standard_D4s_v4"
  tags = local.common_tags
  zone = index(var.instances, each.value) + 1

 os_disk {
    caching = "ReadWrite"
    storage_account_type = "Premium_LRS"
    name = "${each.key}-OS-DISK-00"
  }



} 
1
Any updates on this question? Does it solve your problem?Charles Xu

1 Answers

0
votes

In your ways, it's easy to create one VM with multiple disks, but it's difficult to create multiple VMs with different sizes and numbers of disks. The best way is to use the Terraform module.

The module is similar to the way you used to create one VM with multiple disks, so I'll only show you how to use the module:

variable "vms" {
    type = map(object({
        size = string
        admin_user = string
        admin_password = string
        disks = list(number)
    }))
}

module "vms" {
    for_each = var.vms
    
    source = "./modules/vm"
    resource_group_name = var.rg_name
    vm_name = each.key
    vm = each.value
    disks = each.value["disks"]
    location = var.location
}

terraform.tfvar

rg_name = "charlesVMs"
location = "East US"
vms ={
  azurevm1 = {
    
    size = "Standard_DS1_v2"
    admin_user = "azureuser"
    admin_password = "azureuser@2021"
    disks = [30, 30]
  }
}

This example just provides you a direction to solve your requirement, get more details on another issue. And if you have any questions about this issue, please let me know and I'm willing to help you.