Infrastructure Drift and Policy as Code
Infrastructure as code promises that the repository describes what is running. Drift breaks that promise: someone opens a port in the cloud console during an incident, an autoscaler changes a setting, a teammate applies from a laptop with uncommitted code. The next terraform apply either silently reverts the fix or fails, and for weeks the code tells a story that is not true.
Policy as code addresses a related problem: code that is perfectly in sync can still be wrong — a public storage bucket, an unencrypted database, a security group open to the internet. Writing those rules as automated checks, run on every plan and at the cloud's own boundaries, turns tribal knowledge into enforced guardrails. Together, drift detection and policy checks keep infrastructure both accurate and acceptable.
TL;DR
- Drift is any difference between declared and actual infrastructure; detect it with scheduled plans and cloud configuration services.
- Treat each drift finding deliberately: revert it, adopt it into code, or exclude fields the platform manages.
- Remove the causes: restrict console write access, apply only through CI, and record break-glass changes.
- Policy as code evaluates plans and resources against rules in CI, at apply time, and at cloud or Kubernetes admission.
- Start policies in advisory mode, measure violations, then enforce with documented exceptions.
- Keep policies versioned, tested, and owned like any other code.
Quick Example
A nightly drift check with Terraform, and a policy that blocks SSH open to the internet in any plan:
The drift check runs read-only on a schedule; the policy check runs on every pull request and fails the build before the change can be applied.
Core Concepts
Causes of Drift
Detecting Drift
- Scheduled plans:
terraform plan -detailed-exitcodeor-refresh-onlyper stack, nightly or hourly for critical environments; Pulumi'spreviewandrefreshserve the same purpose. - Managed drift detection in platforms such as HCP Terraform.
- Cloud configuration services — AWS Config, Azure Policy, Google Cloud Asset Inventory and Security Command Center — record changes and evaluate rules even for resources outside your code.
- GitOps controllers for Kubernetes continuously compare cluster state with Git and report or revert differences. See GitOps.
Responding to Drift
Policy as Code
Policies are rules written as code and evaluated automatically. They belong at several layers:
Plan-level checks give the fastest, friendliest feedback; cloud-level guardrails are the backstop that catches console changes and other tools.
Rolling Out Policies
- Write the rule with tests for compliant and non-compliant examples.
- Advisory mode: report violations without blocking, and measure how many exist.
- Fix or except: remediate existing violations, or grant time-limited, documented exceptions.
- Enforce, with a message that tells engineers how to comply.
Best Practices
Make CI the Only Writer
Apply infrastructure only from CI with reviewed plans, and give humans read-only cloud access by default. Break-glass write access should be time-limited and audited, and its changes codified afterwards.
Check Drift Before Every Apply
A plan that shows unexpected changes is a drift signal. Stop and understand them rather than applying everything in the plan.
Version and Test Policies
Keep policies in a repository with tests, review changes, and release them deliberately. A broken policy can block every deployment.
Measure Guardrails
Track drift findings, violation counts, and exception age. Rising drift usually means the code path is too slow or too hard to use during incidents — fix the workflow, not just the symptoms. See Security Misconfiguration.
Common Mistakes
Ignoring Drift Until the Next Apply
Blanket ignore_changes
Policies That Only Run in CI
FAQ
What is infrastructure drift?
The difference between what infrastructure code declares and what actually exists — caused by manual changes, other automation, platform-managed settings, or code that was never applied.
How do I detect drift in Terraform?
Run terraform plan -detailed-exitcode (or terraform plan -refresh-only) on a schedule for each stack. Exit code 2 means the real infrastructure differs from the code or state. Managed platforms such as HCP Terraform can run drift detection for you.
Should drift be fixed automatically?
Sometimes. Automatic reverts suit tightly controlled environments, such as Kubernetes clusters managed by GitOps. For cloud infrastructure, alerting the owner first is safer, because some drift is an emergency fix that must be adopted rather than undone.
What is policy as code?
Writing infrastructure rules — encryption required, no public access, approved regions — as code that is evaluated automatically against plans, resources, or admission requests, instead of relying on manual review.
Which policy tool should I use?
Use OPA with Conftest or a scanner such as Checkov for plan checks in CI, your cloud's native policy service for organization-wide guardrails, and Kyverno or Gatekeeper for Kubernetes. Many teams use several, each at the layer it fits.
Related Topics
- Infrastructure as Code — Declarative infrastructure fundamentals
- Terraform — Plans, state, and lifecycle settings
- Terraform State — How Terraform records what exists
- Kyverno — Policy as code for Kubernetes
- GitOps — Continuous reconciliation from Git
- Security Misconfiguration — The risks guardrails prevent