You wrote the Terraform. You reviewed the plan. You applied it. For one shining moment, your code and your cloud were identical. Then someone opened the console to fix an incident at 2 a.m., bumped a security group rule, and never told anyone. That gap — between what your code says and what's actually running — is drift, and it's the quiet way a well-run Terraform estate slides back into chaos.
- What drift actually is
- What causes drift
- Why drift is dangerous
- How terraform plan detects drift
- The limits of running plan by hand
- Continuous, per-resource detection
- Detect, then decide
- FAQ
What drift actually is
Terraform keeps three things in its head: your configuration (the .tf files), its state (a snapshot of what it believes it manages), and the real resources in your cloud. In a perfect world all three agree. Drift is any divergence between the real resources and what Terraform expects — most often because something changed a resource outside of Terraform's control.
Drift isn't a bug in Terraform. It's the world changing your infrastructure while your code wasn't looking.
What causes drift
- Manual console changes. The classic. An emergency fix, a quick toggle, a "temporary" rule that becomes permanent.
- Other automation. Auto-scaling, AWS-managed updates, lifecycle policies, or a separate script mutating the same resources.
- Provider-side defaults. A cloud provider populates or changes a default attribute you didn't specify.
- Multiple tools, one resource. Two Terraform workspaces — or Terraform plus CloudFormation — both touching the same thing.
- Out-of-band deletes. Someone deletes a resource Terraform still thinks it manages, so the next plan wants to recreate it.
Why drift is dangerous
Drift looks harmless because, day to day, nothing breaks. The danger is in what happens next:
- The silent revert. Someone's emergency console fix is quietly undone the next time anyone runs
terraform apply— reintroducing the very problem they fixed. - The failed apply. Drift can make an unrelated apply error out, blocking a deploy at the worst possible moment.
- The hidden misconfiguration. A security group opened to
0.0.0.0/0by hand won't show up in code review, because it isn't in the code. - The wrong rebuild. If disaster recovery rebuilds from drifted code, you recreate yesterday's infrastructure, not today's.
How terraform plan detects drift
Terraform has drift detection built in. When you run a plan, it refreshes state by reading the real resources from the provider, then compares reality to your configuration:
terraform plan -refresh-only
# Output flags out-of-band changes, e.g.:
# ~ resource "aws_security_group" "web" {
# ~ ingress = [ ... changed outside Terraform ... ]
# }
# Note: Objects have changed outside of Terraform
The -refresh-only mode is the cleanest way to ask "what's drifted?" without proposing config-driven changes. Anything Terraform reports here changed outside of your code. Running this regularly is the foundation of drift detection.
The limits of running plan by hand
Built-in plan is correct but operationally awkward as a drift strategy:
- It only checks what's already in your code. A resource someone created entirely by hand isn't in state, so plan never looks at it — you stay blind to it.
- It's pull, not push. Drift only surfaces when a human remembers to run it. The 2 a.m. change can sit undetected for weeks.
- It's per-workspace. Across dozens of states and modules, "just run plan everywhere on a schedule" becomes its own brittle pipeline to build and babysit.
Continuous, per-resource detection
The operational answer is to detect drift continuously and at the resource level, rather than waiting for someone to run a command. That means re-reading the live account on a schedule, comparing it to the last known-good state, and surfacing exactly which resources and attributes changed.
This is core to how InfraSync works: it re-scans your AWS account on a schedule (read-only), and reports drift per resource — what changed, where, and since when — so a hand-edited security group rule shows up as an alert instead of a surprise during your next deploy. Because the scan also covers resources that were never in your code, it catches the entire category of "created by hand, invisible to plan" drift that built-in tooling misses. If you're still codifying, our AWS-to-Terraform guide and ClickOps migration playbook cover getting there.
Detect, then decide
Detection is only useful if it leads to a decision. When drift shows up, you have three honest options:
- Adopt it. The change was legitimate — update your code to match, so the code stays the source of truth.
- Revert it. The change was a mistake or unauthorised — apply your code to bring reality back in line.
- Investigate it. You don't recognise the change — find out who or what made it before doing either. This is often where a real security finding hides.
The goal isn't zero drift forever — it's zero undetected drift. Surprises are the enemy, not change itself.
A note of caution on auto-remediation: some platforms will automatically apply changes to "fix" drift for you. That's powerful but it means a tool with write access is mutating production based on a diff. A read-only detector that tells you and lets a human decide is a deliberately safer default — and it's why InfraSync detects and reports drift but never writes to your account.
Know the moment your cloud drifts from your code.
InfraSync re-scans your AWS account on a schedule and flags drift per resource — read-only, no write access, no surprise reverts. Set it up in minutes.
Start a free scanFAQ
What is configuration drift in Terraform?
Drift is the difference between the infrastructure described in your Terraform code and state, and the real resources running in your cloud. It happens when something changes a resource outside of Terraform — usually a manual console change, an automated process, or a provider-side default.
How does terraform plan detect drift?
terraform plan refreshes state by reading the real resources from the provider, then compares that reality to your configuration. Differences appear in the plan as changes Terraform would make to bring reality back in line with code. Running plan (especially -refresh-only) on a schedule is the simplest form of drift detection.
Why is drift dangerous?
Drift erodes the guarantee that your code reflects reality. An undetected change can be silently reverted by the next apply, cause an apply to fail, hide a security misconfiguration, or make disaster recovery rebuild the wrong thing. Continuous drift detection turns these surprises into early alerts.