Infrastructure as code promises a single source of truth for cloud resources. In practice, the real cloud often diverges from the declared configuration. Terraform drift detection is the practice of identifying when the actual cloud infrastructure diverges from the declared Terraform infrastructure as code configuration. The gap matters for security, compliance, reliability, and cost, and it requires concrete detection techniques, prevention best practices, and step-by-step remediation workflows that scale across teams and clouds.
Infrastructure drift in Terraform describes a mismatch between the blueprint, your .tf files and modules, and the actual resources running in the cloud. The Terraform state file is the artifact that represents the platform's understanding of that blueprint. When console edits, manual changes, or other automation modify resources outside Terraform, the state file and the real infrastructure fall out of sync. Manual changes and console modifications can silently alter infrastructure, leaving serious blind spots and inconsistencies.
Why Drift Matters and How It Happens
Drift is not a cosmetic issue. The risk potential of drift can range from low to critical, and the impact can affect the system's security, cost, and reliability. Terraform IaC and state files are the only reliable and predictable sources of information about the managed infrastructure.
Common drift sources include:
- Direct console modifications by operators
- Changes made by other automation outside Terraform
- Resource attributes updated by cloud providers automatically
- Imported resources that are later modified out of band
Without detection, teams lose auditability and control. Operational overhead, auditability, and cost implications all increase when drift is discovered late. The tradeoffs between manual processes and automated reconciliation shape how organizations choose to respond.
Native Terraform Detection and Its Limits
Running terraform plan on a schedule is the baseline way to spot drift, since any out of band change will show up as proposed updates. This works well if you already have automation that runs plans regularly and surfaces the results.
Native detection relies on exit codes:
- Exit code 0 means no changes
- Exit code 2 means changes detected
- Exit code 1 means error
A practical drift report script captures this behavior.
```bash
!/bin/bash
drift-report.sh
set -e
echo "=== Terraform Drift Report ==="
echo "Generated: $(date)"
echo ""
terraform init -input=false > /dev/null
Capture plan output
PLANOUTPUT=$(terraform plan -detailed-exitcode 2>&1) || EXITCODE=$?
if [ "${EXITCODE:-0}" -eq 0 ]; then
echo "Status: No drift detected"
elif [ "${EXITCODE:-0}" -eq 2 ]; then
echo "Status: DRIFT DETECTED"
echo ""
echo "Changes:"
echo "$PLANOUTPUT" | grep -A 100 "Terraform will perform"
else
echo "Status: Error during plan"
echo "$PLANOUTPUT"
fi
```
Analyzing drift at scale benefits from structured output.
```bash
Generate plan in JSON format
terraform plan -out=plan.tfplan
terraform show -json plan.tfplan > plan.json
Parse with jq
jq '.resource_changes[] | select(.change.actions | contains(["update"]))' plan.json
```
Native commands provide detection but have limits. They require valid state, correct credentials, and access to all targeted accounts. They do not identify resources that are completely unmanaged by Terraform, and they do not explain why a change occurred.
Automated Continuous Monitoring Patterns
Continuous monitoring moves drift detection from ad-hoc to continuous. Automated continuous monitoring patterns combine remote state with scheduled checks in CI/CD pipelines or monitoring tools.
One zero-cost approach builds a drift detection system using GitHub Actions and Terraform's native exit codes. The workflow automatically discovers all Terraform root modules, runs daily drift checks, and creates GitHub issues when changes are detected. It runs on a daily schedule and supports manual execution via workflow_dispatch.
By leveraging Terraform's built-in exit codes and GitHub's issue tracking, a robust drift detection system can be built using only native features with no external services required. This approach works well for small-to-medium deployments. Larger-scale production use requires additional considerations like multi-account support, sensitive data sanitization, and automated remediation.
Platform-level capabilities accelerate detection and remediation while keeping analysis vendor-neutral except where specific automation examples are introduced.
Terraform Cloud has built-in drift detection:
hcl
terraform {
cloud {
organization = "mycompany"
workspaces {
name = "production"
}
}
}
In Terraform Cloud workspace settings you can enable Automatic speculative plans and set Drift detection to run on schedule. Terraform Cloud runs scheduled drift detection, sends notifications for detected drift, shows drift in the UI, and can auto-queue remediation runs.
Drift-Focused Tooling and Validation
Terraform built in workflows provide the baseline. Drift-focused tooling adds depth.
Tools such as driftctl are built specifically to detect AWS, GCP, or Azure resources that are unmanaged or out of sync with Terraform code, helping you see which parts of your estate have quietly escaped IaC control.
Testing and validation in your pipeline enforce expected outcomes. While not drift tools by themselves, test frameworks like Terratest, TestInfra, and Kitchen Terraform help you enforce that your Terraform changes produce the expected infrastructure and behavior.
A comparison of detection options:
| Approach | Detection Scope | Typical Use | Notes |
|---|---|---|---|
| Terraform plan on schedule | Managed resources only | Baseline CI/CD check | Shows proposed updates for out of band changes |
| Drift-focused tooling | Managed and unmanaged resources | Estate visibility | Identifies resources escaped IaC control |
| Testing and validation | Behavior and outputs | Pipeline quality gate | Ensures changes produce expected infrastructure |
Governance Controls for Prevention
Prevention reduces drift frequency. Governance controls such as policy-as-code and RBAC limit who can make changes and how.
Policy-as-code enforces rules before changes are applied. RBAC restricts console access so manual edits require approval and are logged. Remote state locking prevents concurrent modifications that can corrupt state.
Spacelift's drift detection encompasses monitoring and an intuitive UI to highlight the drift and optionally automate reconciliation. This makes it easy to identify what has changed and how to proceed with investigating it.
Behind the scenes, Spacelift periodically runs proposed runs against your stable stack state on private workers and checks for any differences.
You can configure multiple cron-style schedules, decide whether detection should automatically trigger tracked reconcile runs, and manage all of this either in the UI Settings → Scheduling or as code using the spaceliftdriftdetection Terraform resource.
Control options include:
- Reconcile: When enabled, Spacelift automatically remediates the drift. When infrastructure drift is identified, Spacelift triggers the terraform apply workflow to restore the original state of infrastructure as per the Terraform configuration
- Schedule: This is a simple cron job notation that determines the scanning frequency and compares the state of deployment
The drift detection schedule again plays an important role in confirming mitigation actions post-import/disassociation. This is because there may be a need to either import drift or disassociate infrastructure from the current Terraform configuration.
Remediation Decision Framework
Drift happens, so remediation must be deliberate. Two primary paths exist.
Option 1: Accept Terraform's Desired State
Apply Terraform to bring infrastructure back to desired state.
```bash
Review the changes
terraform plan
Apply to fix drift
terraform apply
```
Option 2: Accept the Drifted State
Update Terraform configuration to reflect the reality in the cloud, then apply.
Auto-remediating Terraform drift is generally not recommended in most production environments due to the potential for unintended changes and outages. Auto-remediation may be appropriate in tightly controlled, low-risk environments where infrastructure changes are fully automated and predictable.
A decision framework considers:
- Risk level of the drifted resource
- Whether the drift was intentional
- Compliance requirements
- Blast radius of remediation
Tool Evaluation Checklist
Selecting drift detection solutions requires a practical tool-evaluation checklist. Factors include operational overhead, auditability, and cost implications.
Key criteria:
- Detection coverage for all cloud providers in use
- Scheduling flexibility with cron-style control
- Integration with existing CI/CD and state backends
- Visibility into which resources drifted and why
- Ability to import drift or disassociate infrastructure
- Remediation controls with approval gates
- Audit logs for compliance
OpenTofu and Licensing Considerations
Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform's existing concepts and offerings. It is a viable alternative to HashiCorp's Terraform, being forked from Terraform version 1.5.6.
Commands and flags are compatible because OpenTofu is forked from Terraform 1.5.6.
Does drift detection apply to OpenTofu as well? Yes, drift detection applies to OpenTofu just as it does to Terraform. Running opentofu plan will detect drift by comparing the current infrastructure state from the state file and real-time cloud queries with the declared configuration.
How to Detect Terraform Drift Automatically
To detect Terraform drift automatically, use terraform plan in combination with remote state and scheduled checks in your CI/CD pipeline or a monitoring tool.
Effective setups combine scheduled plans, notifications, and clear ownership of remediation. Daily checks for production stacks and more frequent checks for critical services balance timeliness with API cost.
Conclusion
Drift detection is not a single command but a layered capability. Native terraform plan provides the foundation for detecting divergence from declared configuration. Automated continuous monitoring patterns extend that foundation into daily or near-real-time checks, with GitHub Actions offering a zero-cost implementation for small-to-medium deployments and platforms like Terraform Cloud and Spacelift providing built-in scheduling, UI visibility, and optional reconciliation.
Governance controls such as policy-as-code and RBAC reduce the likelihood of drift, while remediation decision frameworks ensure that detected changes are handled with appropriate risk assessment rather than blind automation. Tooling such as driftctl expands visibility to unmanaged resources, and testing frameworks help validate that changes produce expected behavior.
Real-world tradeoffs remain. Operational overhead, auditability, and cost implications favor different solutions at different scales. Manual processes give maximum control but delay detection. Automated reconciliation accelerates recovery but requires trust in change predictability.
With remote state, scheduled plans, and clear remediation policies, teams can maintain the desired state for infrastructure across teams, applications, and clouds while keeping the analysis practical and vendor-neutral.