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

更新Terraform中Azure NSG时VM被销毁的原因及解决建议

问题场景

当前所有VM处于运行状态,仅需更新/扩展Azure NSG规则添加新条目。这些NSG规则在初始VM部署阶段已关联至VM网卡,但执行命令terraform apply --var-file=module_directory.tfvars --var-file=updated_nsg_rules.tfvars后,VM被销毁并重建,需找到仅完成NSG规则更新、避免VM重建的方法。


关联NSG与网卡的模块代码

module "vsmart_virtual_interface_NSG_association" {
    source                         = "/Users/reuel/Documents/Terraform/dev_projects/azure_dev/terraform_libs/nsg_assoc"
    location                       = module.Resource_Group.resource_group_location
    virtual_network_interface_ids  = module.vsmart_virtual_interfaces.virtual_network_interface_ids
    network_security_group_rule    = module.Network_Security_Group.network_security_group_rule

    depends_on = [ module.vsmart_virtual_interfaces ]
}

NSG资源定义代码

resource "azurerm_network_security_group" "network_security_group_rule" {
  name = "${var.base_name}_${var.site_name}_nsg" 
  location = var.location 
  resource_group_name = var.resource_group_name

  dynamic "security_rule" {
    for_each = var.nsg_rules
    content {
      name                       = security_rule.value["name"]
      priority                   = security_rule.value["priority"]
      direction                  = security_rule.value["direction"]
      access                     = security_rule.value["access"]
      protocol                   = security_rule.value["protocol"]
      source_port_range          = security_rule.value["source_port_range"]
      destination_port_range     = security_rule.value["destination_port_range"]
      source_address_prefix      = security_rule.value["source_address_prefix"]
      destination_address_prefix = security_rule.value["destination_address_prefix"]
      description                = security_rule.value["description"]
  }
}

Terraform计划中触发VM替换的变更内容

- storage_image_reference { # forces replacement
  - id = "/subscriptions/<ID>/resourceGroups/SDWAN-PODS/providers/Microsoft.Compute/galleries/SDWAN/images/vmanage-20-6-5/versions/20.6.5" -> null }
+ storage_image_reference { # forces replacement
  + id = (known after apply)
  + version = (known after apply)
}

问题原因

VM被销毁重建的触发点并非NSG规则更新,而是VM资源的storage_image_reference字段被标记为强制替换。大概率是VM资源定义中,镜像引用的配置出现变动:比如原本用id引用共享镜像库镜像,现在误改为混用publisher/offer等其他镜像字段,或是镜像相关变量值在本次更新中被意外修改,导致Terraform判定需重新创建VM。

解决步骤
  1. 修复VM镜像配置问题
    找到定义VM的azurerm_linux_virtual_machine或azurerm_windows_virtual_machine资源代码,检查storage_image_reference块:

    • 若之前用id引用共享镜像库镜像,确保该配置未被误删,且不同时混用id与publisher/offer等其他镜像字段,避免配置冲突触发替换。
    • 确认镜像相关变量值未在本次更新中被意外修改。
  2. 确保NSG更新独立于VM生命周期
    现有NSG关联逻辑本身不会触发VM重建,需确认:

    • NSG资源的核心字段(如name)未发生变化,仅security_rule动态块添加新条目,NSG本身为增量更新,不会被替换,因此关联到网卡也不会触发网卡或VM的替换。
    • azurerm_network_interface资源中,NSG关联配置稳定,未因依赖或变量变动导致网卡需重建。
  3. 定向执行NSG更新
    若需优先完成NSG规则更新,可使用Terraform的目标资源参数,仅处理NSG相关资源:

    terraform apply --target=module.Network_Security_Group.azurerm_network_security_group.network_security_group_rule --target=module.vsmart_virtual_interface_NSG_association --var-file=module_directory.tfvars --var-file=updated_nsg_rules.tfvars
    

    该命令会跳过VM相关资源的检查与变更,仅完成NSG规则的更新及关联操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:22:28