You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Terraform实现Azure托管磁盘的单VM独占与多VM共享

问题分析

当前Terraform代码通过嵌套循环将每个VM与所有磁盘模板进行组合,导致共享磁盘(data-disk)被重复创建(每个VM对应一个),无法实现“1个共享盘供多VM使用”的需求。你的核心需求是:

  • 每台VM对应1个专属localdisk(当前逻辑已满足)
  • 仅创建1个data-disk,挂载到所有VM上
解决方案

核心思路是将磁盘分为**专属磁盘(max_shares=1)和共享磁盘(max_shares>1)**两类,分开处理磁盘创建和挂载逻辑:

修改后的managedisk.tf代码

locals {
  # 筛选专属磁盘(max_shares=1),并与每个VM组合
  dedicated_disks_vm_map = 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
        disk_key    = disk
        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" && disk_vals.max_shares == "1"
    }
  ]...)

  # 筛选共享磁盘(max_shares>1),单独处理
  shared_disks = {
    for disk, disk_vals in var.disk_template :
    disk => disk_vals
    if disk_vals.managed_disk_size != "0" && disk_vals.max_shares != "1"
  }

  # 合并所有需要创建的磁盘:专属磁盘用VM+磁盘名作为key,共享磁盘用磁盘名作为key
  all_disks_to_create = merge(
    local.dedicated_disks_vm_map,
    { for k, v in local.shared_disks : v.managed_disk_name => v }
  )

  # 生成共享磁盘的挂载组合:每个共享磁盘对应所有VM
  shared_disk_attachments = merge([
    for disk, disk_vals in local.shared_disks : {
      for vm, vm_vals in var.vm_template :
      "${vm_vals.vm_name}-${disk_vals.managed_disk_name}" => {
        vm          = vm
        vm_name     = vm_vals.vm_name
        disk_key    = disk
        managed_disk_name    = disk_vals.managed_disk_name
        managed_disk_lun     = disk_vals.managed_disk_lun
        managed_disk_caching = disk_vals.managed_disk_caching
      }
    }
  ]...)
}

# 创建托管磁盘:专属磁盘按VM+磁盘名创建,共享磁盘仅创建一次
resource "azurerm_managed_disk" "managed_disk" {
  for_each = local.all_disks_to_create

  name                 = contains(keys(local.shared_disks), each.value.disk_key) ? each.value.managed_disk_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
}

# 挂载专属磁盘到对应VM
resource "azurerm_virtual_machine_data_disk_attachment" "dedicated_disk_attach" {
  for_each = local.dedicated_disks_vm_map

  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
}

# 挂载共享磁盘到所有VM
resource "azurerm_virtual_machine_data_disk_attachment" "shared_disk_attach" {
  for_each = local.shared_disk_attachments

  managed_disk_id    = azurerm_managed_disk.managed_disk[each.value.managed_disk_name].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
}

关键改动说明

  1. 拆分磁盘类型:通过max_shares值区分专属/共享磁盘,避免共享磁盘被重复创建
  2. 磁盘创建逻辑:
    • 专属磁盘:保留原VM+磁盘的组合命名,每个VM对应一个
    • 共享磁盘:仅创建一次,直接使用磁盘模板中的名称
  3. 挂载逻辑拆分:
    • 专属磁盘:仅挂载到对应的VM
    • 共享磁盘:遍历所有VM,将同一个磁盘挂载到每台VM上
  4. 变量复用:保持原var.tf的配置不变,无需修改模板定义

验证效果

执行terraform plan后,你会看到:

  • 2个专属localdisk(test02-localdisk、test03-localdisk)
  • 1个共享data-disk(data-disk)
  • 2次专属磁盘挂载 + 2次共享磁盘挂载,共4条挂载记录

内容的提问来源于stack exchange,提问作者gotothesky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:23:19