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

解决Terragrunt中vsphere_virtual_machine自动更新问题:添加ignore_changes

问题

使用vSphere Provider结合Terragrunt创建虚拟机后,连续执行两次terragrunt apply,即便未修改ept_rvi_mode和hv_mode字段,Terragrunt仍会触发虚拟机的原地更新操作。

原因

vSphere会将ept_rvi_mode和hv_mode字段的值重置为空字符串"",但vSphere Provider定义这些字段时使用的是automatic、on或off这类枚举值,导致Terraform检测到本地配置与远程状态不一致,进而触发不必要的原地更新。

解决方案

在vsphere_virtual_machine资源块中添加lifecycle配置,忽略这两个字段的变更差异。结合你使用的Terraform-VMWare-Modules/vm/vsphere模块,可通过以下方式实现:

在VM目录的terragrunt.hcl中新增generate块,生成资源覆盖配置文件:

generate "vm_lifecycle_override" {
  path      = "vm_lifecycle_override.tf"
  if_exists = "overwrite"
  contents  = <<EOF
resource "vsphere_virtual_machine" "vm" {
  lifecycle {
    ignore_changes = [
      ept_rvi_mode,
      hv_mode
    ]
  }
}
EOF
}
复现步骤
  1. 基于给定配置执行首次terragrunt apply,完成虚拟机创建。
  2. 不修改任何配置,直接执行第二次terragrunt apply,可观察到Terragrunt提示将对虚拟机进行原地更新(针对ept_rvi_mode和hv_mode字段)。
  3. 应用上述解决方案后,再次执行terragrunt apply,将不再触发这两个字段的更新操作。
相关配置参考

根目录terragrunt.hcl

inputs = {
  vmrp                   = "my_cluster/Resources"
  dc                     = "dc1"
  datastore_cluster      = "my_cluster"
  domain                 = "test.local"
  dns_suffix_list        = ["test.local"]
  join_domain            = true
  windomain              = "test.local"
  domain_admin_user      = "${get_env("vsphere_user")}"
  domain_admin_password  = "${get_env("vsphere_pwd")}"
}

generate "config" {
  path      = "config.hcl"
  if_exists = "overwrite"
  contents  = <<EOF
locals {
  env        = "xxx"
}
EOF
}

generate "backend" {
  path      = "backend.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
terraform {
  backend "gcs" {
    bucket  = "${get_env("cloud_bucket")}"
    prefix  = "terraform/${path_relative_to_include()}/terraform.tfstate"
    credentials = "${get_env("cloud_confg")}"
  }
}
EOF
}

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider "vsphere" {
  user           = "${get_env("vsphere_user")}"
  password       = "${get_env("vsphere_pwd")}"
  vsphere_server = "192.x.x.x."

  # 自签名证书允许跳过验证
  allow_unverified_ssl = true
}
EOF
}

VM目录terragrunt.hcl

include "root" {
  path = find_in_parent_folders()
}

locals {
  config = read_terragrunt_config(find_in_parent_folders("config.hcl"))
}

terraform {
  source = "tfr:///Terraform-VMWare-Modules/vm/vsphere//.?version=3.5.0"
}

inputs = {
  vmtemp                 = "TPL-UBUNTU"
  instances              = 1
  cpu_number             = 2
  ram_size               = 4096
  cpu_hot_add_enabled    = true
  cpu_hot_remove_enabled = true
  memory_hot_add_enabled = true
  vmnameformat           = "%02d" # 使用两位带前导零的格式时,虚拟机名称会是类似AdvancedVM01、AdvancedVM02的形式
  vmname                 = "${local.config.locals.envshort}-${basename(get_terragrunt_dir())}-"
  vmfolder               = "FR"
  is_windows_image       = false
  dns_server_list        = ["192.168.2.7"]
  vmgateway              = "192.168.2.254"
  disk_size_gb           = [50]

  network = {
    mynetwork= [""] # 使用DHCP时留空列表;也可使用CIDR格式,例如["192.168.2.134/24"]
  }
}

config.hcl

locals {
  env = "testing"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:17:08