↓ Skip to main content

Reference: Opinion/Experience Post

Take Bakker
Author
Take Bakker

Terraform state drift is treated as an edge case. In my experience it’s more like a regular occurrence that teams aren’t monitoring for.

The scenario is always some variation of: someone makes a manual change in the portal — usually under time pressure, usually with good intentions — and doesn’t update the Terraform code to match. The state file now reflects reality as Terraform last knew it, not reality as it actually is. Next terraform plan shows unexpected changes. The team gets confused, makes it worse, or both.

Why “just don’t make manual changes” doesn’t work
#

The correct answer is correct. It’s also incomplete.

In practice, you’re working with teams that have access to the portal, incidents that require immediate action, and situations where Terraform is too slow or not accessible. Policies and training help. They don’t eliminate the problem.

The more useful question isn’t “how do we prevent drift” — it’s “how do we detect it quickly and respond cleanly.”

What I use
#

terraform plan run on a schedule, with the output reviewed. Not a full apply, just a plan. If the plan shows unexpected changes, that’s the signal. It’s simple, it doesn’t require extra tooling, and it catches most drift within 24 hours.

# In your CI pipeline — run this on a schedule
terraform plan -detailed-exitcode -out = tfplan
# Exit code 2 = changes detected, worth investigating
# Exit code 0 = no changes, state matches reality

For larger environments with multiple workspaces, something like Atlantis or Spacelift gives you this for free. But even without that, a scheduled pipeline job does the job.

When drift happens anyway
#

The important thing is what you do next. Specifically: don’t panic-apply.

Running terraform apply when you don’t fully understand the diff will often make things worse. The manual change might be load-bearing — it was made for a reason. Apply without understanding means you might revert something that’s keeping a service running.

The process I follow:

  1. Identify what drifted and why — talk to whoever made the change if you can
  2. Decide which is correct: Terraform code or the current resource state
  3. If the manual change was wrong, revert it in the portal and let Terraform reconcile
  4. If the manual change was right, update the Terraform code to match (terraform import if needed) before applying anything

Step 4 is the one that gets skipped. People import the drift and move on without updating the code, which means the same drift happens again next time.

The broader point
#

State drift is a symptom. The root cause is usually one of two things: insufficient access control (people can make changes they shouldn’t be making), or Terraform isn’t covering the full resource lifecycle (so people use the portal for parts of the workflow that aren’t automated yet).

Both are worth fixing. But neither fix is instant. Until they’re in place, detecting and responding to drift cleanly is the practical alternative to hoping it doesn’t happen.