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

Terraform创建Azure VM引用共享镜像时version是否必填

问题背景

我近三周一直在使用Terraform,尝试在所属Azure账号中创建自托管GitHub Actions运行器。
我计划使用Azure Compute Gallery中存储的共享Windows VM镜像作为GitHub Actions运行器的基础镜像,但发现这类共享Windows VM镜像通常仅关联publisher、offer、SKU属性,并未像微软官方平台镜像那样关联可直接引用的version属性;我曾通过从现有VM新建镜像的操作验证该情况,确认并非是运维人员遗漏配置版本,而是共享镜像本身确实未挂载可直接通过数据源获取的version属性。

共享镜像示例如下:
Azure共享镜像界面示例

我了解到Terraform中可通过azurerm_windows_virtual_machine和azurerm_virtual_machine两种资源创建VM,我分别使用两种资源测试运行器创建流程。

测试代码1:使用旧版azurerm_virtual_machine资源

data "azurerm_shared_image" "win19_gold_image" {
  provider            = azurerm.gi
  name                = "Windows-2019_base"
  gallery_name        = data.azurerm_shared_image_gallery.cap_win_gold_image_gallery.name
  resource_group_name = "gi-rg"
}

resource "azurerm_virtual_machine" "win_runners_gold_image_based" {
  provider              = azurerm.og
  name                  = "ga-win-gold-1"
  location              = "East US"
  count                 = "1" # 按需调整VM数量
  resource_group_name   = data.azurerm_resource_group.dts_rg.name
  network_interface_ids = [azurerm_network_interface.azure_win_runner_gold_nic[count.index].id,]
  vm_size               = "Standard_D4ads_v5"

  delete_os_disk_on_termination = true
  delete_data_disks_on_termination = true

  storage_image_reference {
    publisher = data.azurerm_shared_image.win19_gold_image.identifier[0].publisher
    offer     = data.azurerm_shared_image.win19_gold_image.identifier[0].offer
    sku       = data.azurerm_shared_image.win19_gold_image.identifier[0].sku
    # 此处报错:Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The value of parameter imageReference.version is invalid." Target="imageReference.version"
  }
  
  storage_os_disk {
    name              = "ga-win-gold-os-disk-1"
    caching           = "None"
    create_option     = "FromImage"
    managed_disk_type = "StandardSSD_LRS"
  }
  
  os_profile {
    computer_name  = "ga-win-gold-1"
    admin_username = "svc"
    admin_password = var.WINDOWS_ADMIN_PASS
  }
  
  os_profile_windows_config {
    enable_automatic_upgrades = true
    provision_vm_agent        = true
  }
  
  storage_data_disk {
    name              = "ga-win-gold-data-disk-1"
    caching           = "None"
    create_option     = "Empty"
    disk_size_gb      = var.disk_size_gb
    lun               = 0
    managed_disk_type = "StandardSSD_LRS"
  }
}

测试代码2:使用新版azurerm_windows_virtual_machine资源

data "azurerm_shared_image" "win19_gold_image" {
  provider            = azurerm.gi
  name                = "Windows-2019_base"
  gallery_name        = data.azurerm_shared_image_gallery.cap_win_gold_image_gallery.name
  resource_group_name = "gi-rg"
}

resource "azurerm_windows_virtual_machine" "azure_win_runner" {
  provider                          = azurerm.og
  name                              = "vm-github-actions-win-${count.index}"
  resource_group_name               = data.azurerm_resource_group.dts_rg.name
  location                          = "East US"
  size                              = var.windows-vm-size
  count                             = "${var.number_of_win_az_instances}"
  network_interface_ids             = [
    azurerm_network_interface.azure_win_runner_nic[count.index].id,
  ]
  computer_name                     = "vm-ga-win-${count.index}"
  admin_username                    = var.windows-admin-username
  admin_password                    = var.WINDOWS_ADMIN_PASS

  os_disk {
    name = "vm-github-actions-win-${count.index}-os-disk"
    caching              = "None"
    storage_account_type = "StandardSSD_LRS"
  }

  source_image_reference {
    publisher = data.azurerm_shared_image.win19_gold_image.identifier[0].publisher
    offer     = data.azurerm_shared_image.win19_gold_image.identifier[0].offer
    sku       = data.azurerm_shared_image.win19_gold_image.identifier[0].sku
    version   = data.azurerm_shared_image.win19_gold_image.identifier[0].version # 提示对象无version属性
    # 手动填version = "latest"或其他版本号,apply时会报错版本不存在
  }

  enable_automatic_updates = true
  provision_vm_agent       = true
}

报错汇总

  • 使用azurerm_virtual_machine资源时,若在storage_image_reference块中省略version配置,会收到如下报错:
Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The value of parameter imageReference.version is invalid." Target="imageReference.version"
  • 若尝试添加version配置,则会收到如下报错:
Error: Unsupported attribute. 
This object does not have an attribute named "version".
  • 使用azurerm_windows_virtual_machine资源时,若移除version参数,Terraform会直接提示该参数为必填项;若手动填入1.0.0、latest这类版本字符串,执行terraform apply阶段会报错提示对应版本不存在;若尝试从data.azurerm_shared_image.cap_win19_gold_image数据源引用version属性,同样会报错提示该对象不存在version属性。
问题原因

这里存在两个核心认知误区:

  1. azurerm_shared_image数据源仅返回镜像定义的基础元数据,不包含镜像版本信息。Azure Compute Gallery中的镜像版本是独立的子资源,和镜像定义分开管理,因此在这个数据源的返回值中永远无法获取version属性。
  2. source_image_reference/storage_image_reference块要求的publisher、offer、sku、version四参数组合,仅适用于Azure Marketplace公共镜像、第三方平台镜像,不支持Azure Compute Gallery中的自定义共享镜像。手动填入latest不生效也是这个原因,共享镜像不识别该版本别名。
解决方案

优先使用官方推荐的新版azurerm_windows_virtual_machine资源(旧版azurerm_virtual_machine已逐步废弃,不建议用于新部署),按以下步骤调整代码:

  1. 新增azurerm_shared_image_versions数据源查询镜像下的所有可用版本,通过排序规则自动获取最新版;如果需要固定版本,可直接使用azurerm_shared_image_version数据源指定版本号。
  2. 删除VM资源中的source_image_reference块,改用source_image_id参数,直接传入查询到的共享镜像版本的资源ID即可,无需再填写publisher、offer、sku、version四个字段。

修正后的核心代码示例(自动取最新镜像版本):

# 查询共享镜像定义
data "azurerm_shared_image" "win19_gold_image" {
  provider            = azurerm.gi
  name                = "Windows-2019_base"
  gallery_name        = data.azurerm_shared_image_gallery.cap_win_gold_image_gallery.name
  resource_group_name = "gi-rg"
}

# 查询该镜像定义下的所有可用版本,按版本号倒序排序
data "azurerm_shared_image_versions" "win19_gold_image_versions" {
  provider            = azurerm.gi
  name                = data.azurerm_shared_image.win19_gold_image.name
  gallery_name        = data.azurerm_shared_image.win19_gold_image.gallery_name
  resource_group_name = data.azurerm_shared_image.win19_gold_image.resource_group_name
  sort_descending     = true
}

# 取排序后第一个结果,即最新版本的镜像ID
locals {
  latest_gold_image_id = data.azurerm_shared_image_versions.win19_gold_image_versions.images[0].id
}

resource "azurerm_windows_virtual_machine" "azure_win_runner" {
  provider                          = azurerm.og
  name                              = "vm-github-actions-win-${count.index}"
  resource_group_name               = data.azurerm_resource_group.dts_rg.name
  location                          = "East US"
  size                              = var.windows-vm-size
  count                             = var.number_of_win_az_instances
  network_interface_ids             = [
    azurerm_network_interface.azure_win_runner_nic[count.index].id,
  ]
  computer_name                     = "vm-ga-win-${count.index}"
  admin_username                    = var.windows-admin-username
  admin_password                    = var.WINDOWS_ADMIN_PASS

  os_disk {
    name                 = "vm-github-actions-win-${count.index}-os-disk"
    caching              = "None"
    storage_account_type = "StandardSSD_LRS"
  }

  # 直接传入镜像版本ID,无需配置source_image_reference块
  source_image_id = local.latest_gold_image_id

  enable_automatic_updates = true
  provision_vm_agent       = true
}

如果需要固定使用某个指定版本,可替换版本查询部分的代码:

data "azurerm_shared_image_version" "win19_gold_image_fixed" {
  provider            = azurerm.gi
  name                = "1.0.0" # 替换为实际需要使用的版本号
  image_name          = data.azurerm_shared_image.win19_gold_image.name
  gallery_name        = data.azurerm_shared_image.win19_gold_image.gallery_name
  resource_group_name = data.azurerm_shared_image.win19_gold_image.resource_group_name
}
# VM中source_image_id直接引用data.azurerm_shared_image_version.win19_gold_image_fixed.id即可

如果坚持使用旧版azurerm_virtual_machine资源,逻辑完全一致:删除storage_image_reference块中的四个自定义参数,新增id字段传入共享镜像版本的资源ID即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:51:18