Terraform v0.12.1销毁无循环却报循环错误求助
Terraform Destroy循环依赖问题:原因、Bug判定与解决办法
我来帮你拆解这个棘手的销毁阶段循环依赖问题:
一、问题根源分析
先看报错里的完整循环链:
module.stack_info.module.project_info.local.project_id → module.stack_info.output.project → module.stack_info.module.project_info.data.google_project.project (destroy) → module.organisation_info.data.google_organization.organization (destroy) → module.stack_info.var.organisation_info → module.stack_info.module.project_info.var.organisation_info → module.stack_info.module.project_info.output.org → 回到local.project_id
核心问题出在模块输出传递形成的闭环,加上旧版本Terraform销毁阶段的依赖分析缺陷:
project-info模块的output.org直接把输入的organisation_info整个对象返回了,相当于把上游模块的依赖又反向传了回来;stack-info模块的output.project又把project-info的所有输出(包括那个org)暴露出去,形成了一个完整的依赖闭环;- 在销毁阶段,Terraform需要按顺序清理数据源和依赖关系:要销毁
google_organization数据源,得先处理依赖它的stack_info模块,但stack_info的输出又依赖project-info的输出,而project-info的输出又依赖organisation_info的存在,死循环就这么产生了。
至于为什么terraform plan -destroy没检测到?因为计划阶段只是做静态依赖逻辑评估,而销毁执行阶段会实际处理资源销毁的顺序,旧版本的Terraform在这个阶段的依赖分析逻辑有漏洞,没在计划阶段发现这个隐藏的闭环。
二、是否属于Terraform Bug?
结合你使用的是Terraform v0.12.1(2019年的老旧版本),这个肯定是旧版本的已知bug:
- 后续的v0.13+版本对模块依赖分析、销毁流程做了大量优化,尤其是对模块输出传递、数据源依赖的处理逻辑;
- 你注释掉
stack-info的project输出就解决问题,也侧面证明旧版本在处理嵌套模块输出的依赖传递时,销毁阶段的分析逻辑有缺陷,误判了循环。
三、解决办法
1. 快速临时修复
直接打破输出闭环:
- 要么删掉
stack-info模块里那个project输出(如果下游模块不需要的话); - 要么修改
project-info模块的输出,不要返回整个organisation_info对象,只返回真正需要的字段:
# project-info模块的输出修改为: output "project_id" { value = local.project_id } output "organization_id" { value = var.organisation_info.organization_id }
这样就切断了依赖闭环,销毁时不会再触发循环。
2. 长期彻底修复
- 升级Terraform版本:强烈建议升级到v0.13及以上的稳定版本(比如最新的v1.x系列),旧版本v0.12有大量已知的依赖分析和模块处理bug,升级后这类问题大概率会自动消失;
- 优化模块依赖设计:
- 避免在模块输出中直接返回整个输入变量对象,只返回下游模块真正需要的字段,减少不必要的依赖传递;
- 明确数据源的依赖关系,避免隐式的跨模块依赖闭环。
3. 验证修复效果
修改后先执行terraform plan -destroy确认没有循环提示,再执行terraform destroy -auto-approve验证销毁流程正常。
内容的提问来源于stack exchange,提问作者Sebastian Nemeth
相关产品推荐
相关产品推荐

