如何捕获Terraform销毁时待删除虚拟机的资源信息?
问题描述
我负责的IaC项目采用 Packer => Terraform => Ansible 流程,在本地VMware vSphere集群创建RHEL虚拟机:
- VMware模块注册输出变量,VM创建完成后,这些变量传入
local_file资源模板生成包含VM名称及其他变量的Ansible清单 - 通过
local_exec运行Ansible,完成新VM的配置(比如加入FreeIPA域,暂无合适Terraform模块支持)
当前核心问题:执行terraform destroy或因VM数量变更触发销毁的apply操作时,需要捕获待销毁VM的名称(即创建阶段的输出变量),以便将其从IPA域移除并完成清理。尝试过多种Destroy Time Provisioners方案,但需要大幅调整现有流程才能生效,想知道是否有办法在销毁阶段获取输出变量来生成待删除VM列表?
可行解决方案
方法1:从Terraform销毁计划提取待销毁VM信息
通过Terraform的计划文件和命令行工具,可直接提取待销毁的VM名称,无需修改现有Terraform代码结构:
- 生成销毁计划文件:
terraform plan -destroy -out=destroy.plan - 将计划转为JSON格式,用
jq过滤出待销毁的VM资源名称:
(注:将terraform show -json destroy.plan | jq -r '.resource_changes[] | select(.change.actions[] == "destroy") | .address' | grep -E 'vmware_virtual_machine|your_vm_module_prefix' | awk -F'[."]' '{print $NF}'your_vm_module_prefix替换为实际的VM模块名称或资源前缀) - 将提取到的VM名称传入预先编写的Ansible清理剧本,执行FreeIPA移除操作,之后再运行
terraform apply destroy.plan完成VM销毁。
方法2:为VM资源添加销毁阶段本地执行器(最小侵入式调整)
无需重构现有流程,只需在VMware模块的vmware_virtual_machine资源中添加destroy-time provisioner,直接在销毁前获取当前VM的名称并触发清理:
resource "vmware_virtual_machine" "rhel_vm" { # 现有VM配置参数... provisioner "local-exec" { when = destroy command = "ansible-playbook -i '${self.name},' cleanup-ipa.yml -e 'target_vm=${self.name}'" interpreter = ["bash", "-c"] } }
self.name直接引用当前VM的名称,无需依赖外部输出变量- 单独编写
cleanup-ipa.yml剧本,实现从FreeIPA域移除指定主机的逻辑 - 如果VM是通过模块批量创建的,将该provisioner放在模块内部的VM资源定义中,确保每个VM销毁时都会触发清理操作。
方法3:结合输出变量与外部脚本批量处理
通过Terraform输出变量维护当前VM列表,再与销毁计划对比得到待清理对象:
- 在Terraform中定义输出变量,输出所有VM的名称:
output "active_vm_names" { value = vmware_virtual_machine.rhel_vm[*].name description = "List of currently deployed RHEL VM names" } - 编写外部脚本(比如bash脚本)执行以下步骤:
- 导出当前VM列表:
terraform output -json active_vm_names > current_vms.json - 生成销毁计划:
terraform plan -destroy -out=destroy.plan - 提取待销毁VM名称(参考方法1的jq命令)
- 对比当前列表与待销毁列表,得到需要清理的VM集合
- 调用Ansible批量执行FreeIPA移除操作
- 最后执行
terraform apply destroy.plan完成销毁
- 导出当前VM列表:
这种方式适合批量销毁多个VM的场景,避免单个VM触发多次Ansible执行,提升清理效率。
内容的提问来源于stack exchange,提问作者RoscoeT
相关产品推荐
相关产品推荐

