0

New to terraform I've been using the count argument to create VMs in Azure. Best practices suggests using For_each argument over using count. I've encountered issues where I wanted to change certain servers configurations.

I've taken some code from peoples recommendations on here. In the code below, in it's current state it will create a managed disk for each vm.

However the managed disk is not independent in that if I change the disk size for the managed disk it will change it for all of the vm's. How can I accomplish to have different disk sizes per VM for managed disks. I did try adding the managed disks to a single key in the variables locals for each vm. However for some reason the plan was going to create two managed disks per vm?

Any pointers/advice would be greatly appreciated!

Under a subdirectory 
#########################################################################################
variable.tf

variable "m_resource_group_name" {
  description = "This is defines the resouce grp name"

}

variable "m_location" {
  description = "This is defines the location"

}

variable "m_subnet_id" {

    description = "The ID of the subnet "
  
}

variable "m_admin_username" {

    description = "admin username"
 
}

 variable "m_vault_name_id" {
   description = "Azure Key Vault data source"
  type        = object({
    id                 = string
    name               = string
    resource_group_name = string
  })
}

variable "winserver-test-pw" {
  description = "admin pw"
}

############################# NEW variable map #######################

variable "vm_map" {
description = "values for the server"
  type = map(object({
    name = string
    size = string
  }))
default = {
  "vm1" = {
    name = "vm1"
    size = "Standard_DC2ds_v3"
    nic = "nic1"
    
  }

  "vm2" = {
    name = "vm2"
    size = "Standard_DC2ds_v3"
    nic = "nic1"
    
  }
}
}

variable "disk_template" {
  type = map(any)
  default = {
    disk1 = {
      managed_disk_name    = "data-disk1"
      managed_disk_type    = "StandardSSD_LRS"
      managed_disk_size    = "10"
      managed_disk_lun     = "2"
      managed_disk_caching = "ReadWrite"
      create_option        = "Empty"
      os_type              = "Windows"
    }
  }
}
#####################################################################################################
locals.tf
# Managed Disk

locals {
  disk_vm_flat = merge([
    for vm, vm_vals in var.vm_map : {
      for disk, disk_vals in var.disk_template :
      "${vm_vals.name}-${disk_vals.managed_disk_name}" =>  {
        name                 = vm_vals.name
        managed_disk_name    = disk_vals.managed_disk_name
        managed_disk_size    = disk_vals.managed_disk_size
        managed_disk_lun     = disk_vals.managed_disk_lun
        managed_disk_type    = disk_vals.managed_disk_type
        managed_disk_caching = disk_vals.managed_disk_caching
        os_type              = disk_vals.os_type
        create_option        = disk_vals.create_option
      }  if disk_vals.managed_disk_size != "0"
    }
  ]...) # Do not remove the dots. 
}

#######################################################################################################

main.tf

resource "azurerm_network_interface" "nic-multi-vms-01" {
  for_each            = var.vm_map
  name                = "${each.value.name}-nic" #append the keyname to nic at the end
  location            = var.m_location
  resource_group_name = var.m_resource_group_name

  ip_configuration {
    name                          = "${each.value.name}-ipconf"
    subnet_id                     = var.m_subnet_id
    private_ip_address_allocation = "Dynamic"

  }
}


resource "azurerm_windows_virtual_machine" "winservertest" {


  for_each = var.vm_map
  name                 = each.value.name
  resource_group_name = var.m_resource_group_name
  location            = var.m_location
  size                = each.value.size
  admin_username      = var.m_admin_username
  admin_password      = var.winserver-test-pw
  patch_mode               = "Manual" 
  enable_automatic_updates = false 
  network_interface_ids = [
    azurerm_network_interface.nic-multi-vms-01[each.key].id
  ]
  

os_disk {
    name = "${each.value.name}-OS"
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
    disk_size_gb         = 127
  }

source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter"
    version   = "latest"
  }
}


resource "azurerm_managed_disk" "managed_disk" {
  for_each = local.disk_vm_flat
  name     = "${each.value.name}-${each.value.managed_disk_name}"
  location             = var.m_location
  resource_group_name  = var.m_resource_group_name
  storage_account_type = each.value.managed_disk_type
  create_option        = each.value.create_option
  os_type              = each.value.os_type
  disk_size_gb         = each.value.managed_disk_size
}

resource "azurerm_virtual_machine_data_disk_attachment" "disk_attach" {
  for_each = local.disk_vm_flat
  managed_disk_id = azurerm_managed_disk.managed_disk[each.key].id
  lun             = each.value.managed_disk_lun
  caching         = each.value.managed_disk_caching
  virtual_machine_id = azurerm_windows_virtual_machine.winservertest[each.value.name].id #amended
}



# ############################
# ### output info
# ############################

output "vm_ids" {
  value = { for vm, vm_vals in var.vm_map : vm => vm_vals }
}




1 Answer 1

0

This happens because you have one disk_template for all VMs. If you want to have different disk sizes for each vm, you have to move your managed_disk_size into var.vm_map. This way you can have different disk sizes for different VMs.

Sign up to request clarification or add additional context in comments.

2 Comments

I did try this. "I did try adding the managed disks to a single key in the variables locals for each vm. However for some reason the plan was going to create two managed disks per vm?".
I've re-tested adding each managed disk to into each key defined for each vm in locals. now get an error saying "##[error]Terraform command 'plan' failed with exit code '1'. ##[error]╷ │ Error: Unsupported attribute │ │ on winserver_mod/locals.tf line 16, in locals: │ 16: } if disk_vals.managed_disk_size != "0" "

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.