Terraform如何优先销毁VPN资源再删除其他关联资源
解决方案
不需要调整parallelism参数,通过显式声明资源依赖即可强制控制删除顺序。
Terraform按照资源依赖关系的逆序执行销毁操作:如果资源X依赖资源Y,创建阶段会先完成Y的创建再启动X的创建,销毁阶段则会优先完成X的全量删除流程,再启动Y的删除。当前配置中,脚本创建的VPN资源和安全组没有任何显式关联,Terraform会将二者判定为同级无依赖资源,默认并行触发删除,才会出现安全组被占用的报错。
具体修改点
- 建立VPN资源对安全组的显式依赖,两种实现二选一即可:
- 隐式依赖:在
null_resource.make_vpn的triggers中加入安全组的ID属性引用,Terraform解析配置时会自动识别依赖关系 - 显式依赖:在
null_resource.make_vpn中添加depends_on元参数,直接指定依赖的安全组资源
- 隐式依赖:在
- 补全删除流程的可靠性校验:
- 移除destroy provisioner中的
on_failure = continue配置(默认值为fail),避免VPN删除失败时Terraform跳过错误直接执行后续安全组删除 - 调整
delete_vpn_server.sh脚本逻辑:调用VPN删除接口后增加轮询校验,持续查询VPN状态,直到确认VPN实例完全删除、与安全组的绑定关系彻底释放后,脚本再返回0退出码。Terraform只有收到destroy provisioner的成功退出信号,才会判定null_resource删除完成,继续推进后续资源的销毁。
- 移除destroy provisioner中的
修改后参考配置
resource "<cloud_provider>_security_group" "sg" { name = format("%s-%s", local.name, "sg") vpc = var.vpc_id resource_group = var.resource_group_id } resource "null_resource" "make_vpn" { # 隐式依赖方式:在triggers中引用安全组ID,自动建立依赖关系 triggers = { vpn_name = var.vpn_name local_script = local.scripts_location sg_id = <cloud_provider>_security_group.sg.id } # 显式依赖方式:如果不想修改triggers,打开下方注释即可,和上面的隐式依赖二选一 # depends_on = [ # <cloud_provider>_security_group.sg # ] provisioner "local-exec" { command = "${local.scripts_location}/login.sh" interpreter = ["/bin/bash", "-c"] environment = { API_KEY = var.api_key } } provisioner "local-exec" { command = local_file.make_vpn.filename } provisioner "local-exec" { when = "destroy" command = <<EOT ${self.triggers.local_script}/delete_vpn_server.sh ${self.triggers.vpn_name} EOT # 移除on_failure = continue配置,删除失败时直接中断流程 } }
效果说明
配置调整完成后,Terraform生成的资源依赖图会明确两个资源的先后关系,执行terraform destroy时会严格先执行VPN删除流程,等VPN彻底清理完成、安全组绑定关系释放后,再启动安全组删除操作,全程不需要修改并行度参数,符合生产环境规则要求。
内容的提问来源于stack exchange,提问作者disp_name
相关产品推荐
相关产品推荐

