beginner 3 min answer

You run `terraform plan` on a production workspace where nothing has been committed for three weeks. The plan proposes 23 changes. Nobody has touched the console. Why does this happen, and what should you do about each kind?

driftterraformprovidersdefaultsinfrastructure-as-code
Show the full answer Hide the answer

The mechanism

A plan is a three-way comparison: your configuration, the recorded state, and what the provider reports the real resource looks like now. A difference in any pair produces a proposed change, and only some of those differences are drift in the sense people mean.

Four causes, and the right response differs for each:

1. A provider version changed. The provider is a dependency, and a new minor version can set a previously-unmanaged attribute, change a default, or begin reporting a field it ignored before. If the provider is not pinned, terraform init may have upgraded it and the plan reflects the new provider rather than a changed world. Response: pin the provider version, then upgrade deliberately and read the plan the upgrade produces.

2. Defaults the cloud computes for you. You did not specify a field, the platform assigned one, and depending on the resource the provider may now want to reconcile it. Response: either specify the value explicitly, or declare it out of scope with an ignore rule — and prefer specifying, because an ignore rule hides genuine change forever.

3. Something outside Terraform changed the resource. An autoscaler adjusted a capacity, a platform service added a tag, a security tool attached a policy, a colleague used the console during an incident. Response: decide who owns the field. If another system legitimately manages it, tell Terraform to ignore that field; if a human changed it by hand, fold the change into the configuration so the next apply does not revert it.

4. The configuration was changed and never applied. Someone merged and the pipeline did not run, so the plan is correctly telling you about work in the queue. Response: apply it — and fix the pipeline, because unapplied merged configuration is how a repository stops being the source of truth.

What to do with the 23

Read them as four piles, not as one number. Reconciling everything blindly is how an autoscaler's capacity gets reset to a written value at the wrong moment, and ignoring everything is how a repository becomes fiction. The useful discipline is that every field is owned by exactly one system, and a drift report is mostly a list of fields whose ownership was never decided.

Why this becomes serious

Drift is a correctness problem when it is silent. The characteristic failure is a disaster-recovery exercise in which the environment rebuilt from code differs from the one that was running, and nobody knew because the plan had been noisy for a year and stopped being read. The second failure is that an urgent change becomes unsafe: with 23 unexplained changes pending, applying one line means applying 24.

When this is not worth chasing

A team with 200 resources and weekly applies will see drift and can handle it by reading the plan each time. Continuous drift detection earns its cost at the scale where a plan is 14 minutes and nobody reads it, and even then the useful output is not an alert per difference — a drift detector that fires 200 alerts a day gets muted, which is worse than not having one. Choose a detector that reports the number of unexplained differences per workspace as a trend, with alerting only on the resources where a difference would be dangerous.