← 中文资源

简体中文版本

定时检测 Terraform 基础设施漂移

每晚执行只读 plan,利用 detailed exit code 区分无变化、漂移与错误,并在真正发生漂移时告警,而不是等到下次 apply 失败。

阅读英文原文

概述

Terraform 假设自己是唯一的写入方。当有人在控制台或其他工具中修改资源后,state 仍描述旧配置,直到下一次 plan 才会暴露。那次 plan 可能在发布过程中把手工修改改回去,也可能因为资源与 provider 预期不符而失败。定时执行只读 plan 可以让偏差在发生当天就可见,此时修改者还记得原因。

步骤

  1. 以只读方式执行 plan 并获取细分退出码:
terraform plan -detailed-exitcode -lock=false -input=false -out=drift.tfplan
  1. 把漂移结果转成可读报告:
terraform show -no-color drift.tfplan | head -60
  1. 在定时任务中仅在退出码为 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"
  1. 针对当前已部署的版本执行 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。
  • 漂移报告需要定期人工评审,否则告警等同于没有。