如何在Terraform中更换VM的Key Vault或凭据且不销毁虚拟机
在Terraform里更换虚拟机关联的Key Vault时,执行terraform apply会触发原有虚拟机销毁并重建新的关联新Key Vault的虚拟机。尝试添加lifecycle(prevent_destroy = true)后,出现以下错误:
Error: Instance cannot be destroyed
on .terraform\modules\avd_vm\Modules\AVD_VM\main.tf line 388:
388: resource "azurerm_windows_virtual_machine" "acumen_vm_kv" {Resource module.avd_vm.azurerm_windows_virtual_machine.acumen_vm_kv has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.
解决方案
1. 核心原因说明
Azure虚拟机与Key Vault的关联信息(比如磁盘加密密钥存储、登录凭据来源)属于创建时的不可变属性,Terraform的azurerm_windows_virtual_machine资源默认将这类属性变更判定为需要销毁重建虚拟机,这是触发当前问题的根源。
2. 不销毁虚拟机的实操步骤
第一步:移除prevent_destroy配置
先删掉资源块中的lifecycle { prevent_destroy = true },避免执行apply时被错误阻塞。
第二步:手动更新Azure资源+同步Terraform状态
- 先通过Azure门户或Azure CLI,手动修改虚拟机的Key Vault关联配置(比如更换磁盘加密用的Key Vault、替换存储管理员凭据的Key Vault)。
- 修改Terraform代码中对应的Key Vault参数(比如
key_vault_id、secret_id等字段)。 - 执行
terraform plan,此时Terraform仍会提示要销毁重建虚拟机,先执行命令移除原有虚拟机的状态记录:terraform state rm module.avd_vm.azurerm_windows_virtual_machine.acumen_vm_kv - 将修改后的虚拟机重新导入Terraform状态(替换命令中的占位符为实际信息):
terraform import module.avd_vm.azurerm_windows_virtual_machine.acumen_vm_kv /subscriptions/<订阅ID>/resourceGroups/<资源组名>/providers/Microsoft.Compute/virtualMachines/<虚拟机名> - 再次执行
terraform plan,此时应显示无资源销毁操作,仅同步配置差异,确认后执行terraform apply完成更新。
第三步:恢复prevent_destroy配置(可选)
状态同步完成后,可重新添加lifecycle { prevent_destroy = true },防止后续误操作销毁虚拟机。
3. 替代方案:用扩展管理凭据
如果只是更换登录凭据的Key Vault,可放弃在虚拟机资源中直接配置,改用azurerm_virtual_machine_extension资源通过Key Vault动态拉取凭据。后续更换Key Vault只需修改扩展配置,不会触发虚拟机重建。
内容的提问来源于stack exchange,提问作者KayMan

