skip to Main Content

enter image description hereI have created and used Azure’s Managed Disk using the Terraform Code as below. However, the fatal drawback of this code is that it creates as many managed disks as the number of VMs.

I want to implement it as below.

  1. I want to create "localdisk" as many as the number of VMs, that is, if there are two VMs, I want to create one each.(The code I have now is implemented like this)

  2. For "data-disk", I want to share 1 "data-disk" in 2 VMs and use it.

Currently, my terraform code is as follows.

  • managedisk.tf
locals {
  disk_vm_flat = merge([
    for vm, vm_vals in var.vm_template : {
      for disk, disk_vals in var.disk_template :
      "${vm_vals.vm_name}-${disk_vals.managed_disk_name}" => {
        vm      = vm
        vm_name = vm_vals.vm_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
        max_shares           = disk_vals.max_shares
      } if disk_vals.managed_disk_size != "0"
    }
  ]...)
}

resource "azurerm_managed_disk" "managed_disk" {
  for_each = local.disk_vm_flat
  name     = "${each.value.vm_name}-${each.value.managed_disk_name}"
  location             = var.location
  resource_group_name  = data.azurerm_resource_group.system_rg_name.name
  storage_account_type = each.value.managed_disk_type
  create_option        = each.value.create_option
  max_shares           = each.value.max_shares
  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.vm[each.value.vm].id
}
  • var.tf
variable "vm_template" {
  type = map(any)
  default = {
    vm2 = {
      vm_name      = "test02"
      hostname     = "test02"
      os_publisher = "MicrosoftWindowsServer"
      os_offer     = "WindowsServer"
      os_sku       = "2022-datacenter-azure-edition"
      license_type = "Windows_Server"
      os_version   = "latest"
      osdisk_type  = "StandardSSD_LRS"
      osdisk_size  = "128"
      vm_type      = "Standard_D4s_v5"
      nic          = "nic01"
      os_disk      = "osdisk01"
    }
    vm3 = {
    vm_name      = "test03"
    hostname     = "test03"
    os_publisher = "MicrosoftWindowsServer"
    os_offer     = "WindowsServer"
    os_sku       = "2022-datacenter-azure-edition"
    license_type = "Windows_Server"
    os_version   = "latest"
    osdisk_type  = "StandardSSD_LRS"
    osdisk_size  = "128"
    nic          = "nic01"
    os_disk      = "osdisk01"
    }
  }
}
variable "disk_template" {
  type = map(any)
  default = {
    disk1 = {
      managed_disk_name    = "localdisk"
      managed_disk_type    = "StandardSSD_LRS"
      managed_disk_size    = "10"
      managed_disk_lun     = "1"
      managed_disk_caching = "ReadWrite"
      create_option        = "Empty"
      os_type              = "Windows"
      max_shares           = "1"
    }
    disk2 = {
      managed_disk_name    = "data-disk"
      managed_disk_type    = "StandardSSD_LRS"
      managed_disk_size    = "10"
      managed_disk_lun     = "2"
      managed_disk_caching = "ReadWrite"
      create_option        = "Empty"
      os_type              = "Windows"
      max_shares           = "2"
    }
  }
}

Is there anyone who can help?

2

Answers


  1. Chosen as BEST ANSWER

    I wrote the following code with some hints from your help. Can we make it a little simpler? @Marcin

    # ############################
    # ### Managed Disk
    # ############################
    locals {
      disk_vm_flat = merge([
        for vm, vm_vals in var.vm_template : {
          for disk, disk_vals in var.disk_template :
          "${vm_vals.vm_name}-${disk_vals.managed_disk_name}" => {
            vm      = vm
            vm_name = vm_vals.vm_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"
        }
      ]...)
    }
    
    resource "azurerm_managed_disk" "managed_disk" {
      for_each = local.disk_vm_flat
      name     = "${each.value.vm_name}-${each.value.managed_disk_name}"
      location             = var.location
      resource_group_name  = data.azurerm_resource_group.system_rg_name.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.vm[each.value.vm].id
    }
    
    # ############################
    # ### shared Managed Disk
    # ############################
    data "azurerm_virtual_machine" "shared_vm01" {
        name = var.vm_template.vm1.vm_name
        resource_group_name = data.azurerm_resource_group.system_rg_name.name
        depends_on         = [azurerm_windows_virtual_machine.vm, azurerm_resource_group.system_rg]
    }
    
    data "azurerm_virtual_machine" "shared_vm02" {
        name = var.vm_template.vm2.vm_name
        resource_group_name = data.azurerm_resource_group.system_rg_name.name
        depends_on         = [azurerm_windows_virtual_machine.vm, azurerm_resource_group.system_rg]
    }
    
    resource "azurerm_managed_disk" "shared_disk" {
      for_each = var.shared_disk
      name     = "${each.value.managed_disk_name}"
      location             = var.location
      resource_group_name  = data.azurerm_resource_group.system_rg_name.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
      max_shares           = each.value.max_shares
    }
    
    resource "azurerm_virtual_machine_data_disk_attachment" "shared_disk_attach01" {
      for_each = var.shared_disk
      managed_disk_id = azurerm_managed_disk.shared_disk[each.key].id
      lun             = each.value.managed_disk_lun
      caching         = each.value.managed_disk_caching
      virtual_machine_id = data.azurerm_virtual_machine.shared_vm01.id  # VM ID
    }
    
    resource "azurerm_virtual_machine_data_disk_attachment" "shared_disk_attach02" {
      for_each = var.shared_disk
      managed_disk_id = azurerm_managed_disk.shared_disk[each.key].id
      lun             = each.value.managed_disk_lun
      caching         = each.value.managed_disk_caching
      virtual_machine_id = data.azurerm_virtual_machine.shared_vm02.id # VM ID
    }
    
    
    # ############################
    # ### output info
    # ############################
    
    output "vm_ids" {
      value = { for vm, vm_vals in var.vm_template : vm => vm_vals }
    }
    

  2. The problem stems from the fact that you are mixing localdisk and data-disk in a single variable var.disk_template. Altough you could hack up TF code for that, it will be simply overly complex and confusing.

    Thus, the best way, imo, is to have a separate variable for data-disk with the associated separate resource. I assume that you have only one shared drive, as your diagram suggest that. For example (the code probably needs some adjustment to work properly, but it shows the overall idea behind the new design):

    variable "disk_template" {
      type = map(any)
      default = {
        disk2 = {
          managed_disk_name    = "data-disk"
          managed_disk_type    = "StandardSSD_LRS"
          managed_disk_size    = "10"
          managed_disk_lun     = "2"
          managed_disk_caching = "ReadWrite"
          create_option        = "Empty"
          os_type              = "Windows"
          max_shares           = "2"
        }
      }
    }
    
    variable "disk_template_shared" {
      type = map(any)
      default = {
        data-disk1 = {
          managed_disk_name    = "data-disk"
          managed_disk_type    = "StandardSSD_LRS"
          managed_disk_size    = "10"
          managed_disk_lun     = "2"
          managed_disk_caching = "ReadWrite"
          create_option        = "Empty"
          os_type              = "Windows"
          max_shares           = "2"
        }
      }
    }
    

    then

    
    resource "azurerm_managed_disk" "managed_disk" {
      for_each = local.disk_vm_flat
      name     = "${each.value.vm_name}-${each.value.managed_disk_name}"
      location             = var.location
      resource_group_name  = data.azurerm_resource_group.system_rg_name.name
      storage_account_type = each.value.managed_disk_type
      create_option        = each.value.create_option
      max_shares           = each.value.max_shares
      os_type              = each.value.os_type
      disk_size_gb         = each.value.managed_disk_size
    }
    
    resource "azurerm_managed_disk" "managed_disk_shared" {
      for_each = var.disk_template_shared
      name     = "${each.value.managed_disk_name}"
      location             = var.location
      resource_group_name  = data.azurerm_resource_group.system_rg_name.name
      storage_account_type = each.value.managed_disk_type
      create_option        = each.value.create_option
      max_shares           = each.value.max_shares
      os_type              = each.value.os_type
      disk_size_gb         = each.value.managed_disk_size
    }
    
    

    and the attachments:

    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.vm[each.value.vm].id
    }
    
    resource "azurerm_virtual_machine_data_disk_attachment" "disk_attach_shared" {
      for_each = var.vm_template
      managed_disk_id = azurerm_managed_disk.managed_disk_shared["data-disk1"].id
      lun             = each.value.managed_disk_lun
      caching         = each.value.managed_disk_caching
      virtual_machine_id = azurerm_windows_virtual_machine.vm[each.value.vm].id
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search