概述
Terraform 假设自己是唯一的写入方。当有人在控制台或其他工具中修改资源后,state 仍描述旧配置,直到下一次 plan 才会暴露。那次 plan 可能在发布过程中把手工修改改回去,也可能因为资源与 provider 预期不符而失败。定时执行只读 plan 可以让偏差在发生当天就可见,此时修改者还记得原因。
步骤
- 以只读方式执行 plan 并获取细分退出码:
terraform plan -detailed-exitcode -lock=false -input=false -out=drift.tfplan
- 把漂移结果转成可读报告:
terraform show -no-color drift.tfplan | head -60
- 在定时任务中仅在退出码为 2 时告警:
- id: plan
run: terraform plan -detailed-exitcode -lock=false -input=false -out=drift.tfplan
continue-on-error: true
- if: steps.plan.outputs.exitcode == '2'
run: terraform show -no-color drift.tfplan >> "$GITHUB_STEP_SUMMARY"
- 针对当前已部署的版本执行 plan,避免把未发布的代码改动当成漂移:
git checkout v1.4.0
terraform plan -input=false -detailed-exitcode -lock=false
验证
退出码 0 表示无变化,2 表示存在漂移或待应用变更,1 表示 plan 本身失败。验证时应分别构造三种情况:干净环境返回 0;手工修改安全组后返回 2 并给出属性差异;故意写错变量后返回 1 且告警文案不同。使用 -lock=false 可以避免夜间任务阻塞正常发布。
注意事项
- 只读 plan 无法发现已从 state 中移除的资源。
- 大规模环境下 refresh 较慢且可能触发限流,应按 stack 拆分。
- 已部署但未发布的代码改动会被误判为漂移,应以发布标签为准。
- provider 默认值可能造成永久 diff,确认后可添加精确的
ignore_changes。 - 漂移报告需要定期人工评审,否则告警等同于没有。