I want CI to fail when someone changes infra in the console instead of Terraform. terraform plan exits 0 even when there is drift. How do I detect it properly?
A Terraform drift detector that runs in CI
Ended up ~80 lines of Go plus a GitHub Action. The interesting part was ignoring managed-by-someone-else tags.
terraform plan -detailed-exitcode is the piece you're missing:
0— no changes1— error2— changes present
terraform plan -detailed-exitcode -out=tfplan
Exit 2 in a scheduled run means drift, because nothing in the repo changed.
The subtlety is that you'll get false positives from anything mutated outside Terraform by design — autoscaling group sizes, tags applied by AWS Config, aws: prefixed tags. Parse the JSON plan and filter those out rather than failing the build on them.
How do I filter reliably? String matching on resource names feels fragile.
Don't match names — match on the changed attributes, which the JSON plan gives you structurally:
terraform show -json tfplan > plan.json
Each entry in resource_changes[] has change.before and change.after. Diff those two objects and you get the exact attribute paths that moved. Then keep an ignore list of paths, not resources:
desired_capacity
tags.aws:*
tags.kubernetes.io/*
That's stable across renames and refactors, because it describes what changed rather than which thing changed. Fail the build only when a non-ignored path appears.
Comments
Sign in to join the conversation.
- No comments yet.