DEV Community

Cover image for Implementing Terraform Drift Detection in Your Workflow
Devin Rosario
Devin Rosario

Posted on

Implementing Terraform Drift Detection in Your Workflow

Your Terraform state file says you have a t2.micro EC2 instance. AWS console shows t2.4xlarge. Cost difference? About $270 monthly versus $1,100 monthly. Multiply that across 50 resources changed manually during last quarter's incident response...

Yeah, drift does not announce itself politely. It just quietly drains budgets while creating security holes nobody notices until something breaks spectacularly.

What Terraform Drift Actually Looks Like in Production

Configuration drift occurs when infrastructure in reality does not match what Terraform configuration files describe. Imagine building automated systems to manage servers, databases, networks through code. Someone logs into AWS console at 3 AM during an outage, makes an emergency fix by opening port 22 to 0.0.0.0/0. Incident resolves, everyone goes home, nobody updates the Terraform code.

Three months pass. Security audit discovers that SSH port is wide open to the entire internet on production servers. Compliance violation, potential data breach vector, and absolutely zero documentation explaining why this exists. That's drift in action, creating blind spots in infrastructure management.

According to real implementation data from companies running multi-cloud environments, drift happens way more frequently than teams admit. Manual console changes, overlapping automation tools, emergency hotfixes... all create situations where actual infrastructure state deviates from code.

The Financial Reality Nobody Talks About Publicly

Database instance type drifts from m5.large to m5.4xlarge. Seems minor until you calculate costs. M5.large runs approximately $175 monthly in US East regions. M5.4xlarge? Try $700 monthly. Single resource drift costs an extra $6,300 annually.

Now scale that. How many resources does your infrastructure contain? Fifty databases? Hundreds of EC2 instances? Load balancers auto-scaling beyond specifications? S3 buckets with wrong storage classes burning money on frequent-access pricing when archive tiers would work?

Companies managing infrastructure for mobile app development Houston projects see this constantly – microservices architectures with dozens of dependencies where small drifts compound into massive cost overruns. Application servers scaled manually during traffic spikes but never scaled back down. Monitoring showed 200 instances running when applications only needed 50.

Real Cost Breakdown Table:

Resource Type Intended Config Drifted Config Monthly Cost Impact
RDS m5.large 1 instance m5.4xlarge +$525
EC2 t3.medium 10 instances 25 instances +$600
EBS gp3 500GB 2TB unattached +$160
NAT Gateway 1 gateway 3 gateways +$90
Total Monthly $470 $1,845 +$1,375

This example shows just four resource types drifting. Production environments contain hundreds or thousands of resources.

Code-Level Detection Using Native Terraform

The terraform plan command with -detailed-exitcode flag returns specific exit codes revealing drift status:

# Basic drift detection
terraform plan -detailed-exitcode

# Exit codes mean:
# 0 = No changes needed (no drift)
# 1 = Error occurred
# 2 = Changes detected (drift exists)
Enter fullscreen mode Exit fullscreen mode

Integrate this into CI/CD pipelines for automated alerts:

#!/bin/bash
terraform plan -detailed-exitcode -out=tfplan
EXIT_CODE=$?

if [ $EXIT_CODE -eq 2 ]; then
    echo "DRIFT DETECTED - Infrastructure deviates from code"
    # Send alert to Slack/PagerDuty
    curl -X POST -H 'Content-type: application/json' \
    --data '{"text":"Terraform drift detected in production"}' \
    $SLACK_WEBHOOK_URL
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

For more detailed analysis, terraform refresh updates state files with current infrastructure reality without making changes:

# Refresh state to reflect current infrastructure
terraform refresh

# Show specific resource current state
terraform state show aws_instance.production_server

# List all resources Terraform manages
terraform state list
Enter fullscreen mode Exit fullscreen mode

Real Company Implementation: How Spacelift Caught $47K Annual Waste

Team managing infrastructure across AWS, GCP, Azure implemented automated drift detection using Spacelift. First drift scan revealed shocking results – EC2 instances manually terminated three months prior still existed in Terraform state. Monthly billing showed charges for "deleted" resources.

Further investigation uncovered 15 orphaned RDS snapshots costing $23 monthly each. Snapshot retention policy drifted when someone manually adjusted settings to troubleshoot backup issues. Nobody reverted changes or updated code.

Security group rules showed major drift too. Development team opened temporary firewall rules for debugging, forgot to close them. Production databases had 12 unnecessary ingress rules exposing services to internal networks that should not access them.

Total annual waste from undetected drift? $47,000. That's real money saved just by implementing continuous monitoring.

Setting Up Continuous Detection (Not Just Pre-Deployment Checks)

Most teams run terraform plan before deployments. Great, but insufficient. Drift happens between deployments – manual changes, auto-scaling policies, disaster recovery procedures, cost-optimization scripts...

Configure cron-based scanning for continuous monitoring:

# Drift detection schedule config (Spacelift example)
resource "spacelift_drift_detection" "production" {
  stack_id = spacelift_stack.production.id

  # Scan every 15 minutes for critical infrastructure
  schedule = ["*/15 * * * *"]

  # Auto-reconcile security-related drift immediately
  reconcile = true
  reconcile_on_drift_only = ["aws_security_group", "aws_iam_*"]

  # Notify specific channels
  webhook_url = var.slack_security_channel
}
Enter fullscreen mode Exit fullscreen mode

For less critical resources, hourly or daily scans balance visibility against API rate limits and cost.

Drift Remediation: Two Philosophies, Both Valid

When drift gets detected, two primary approaches exist for remediation.

Reconciliation means reverting infrastructure to match Terraform code:

# Reapply configuration to fix drift
terraform apply -auto-approve

# Terraform recreates resources matching code specifications
# Security groups close, instances return to correct types
# Manual changes get overwritten
Enter fullscreen mode Exit fullscreen mode

Use reconciliation for security-critical drift. Someone opened SSH to world? Close it immediately through code reapplication. Do not wait for meetings or approvals. Security first.

Code Alignment updates Terraform to reflect current infrastructure reality:

# Before (original code)
resource "aws_instance" "app_server" {
  instance_type = "t3.medium"
  # ...
}

# After (aligned to drift)
resource "aws_instance" "app_server" {
  instance_type = "t3.large"  # Updated to match manual change
  # ...
}
Enter fullscreen mode Exit fullscreen mode

Use code alignment when drift represents legitimate operational improvements made during incidents. Database scaled up during traffic spike and performance improved significantly? Update code to match, then optimize properly during business hours.

Third option rarely discussed: Pull request workflows for code alignment:

# GitHub Actions workflow for drift PR creation
name: Drift Code Alignment
on:
  schedule:
    - cron: '0 */6 * * *'

jobs:
  align-code:
    runs-on: ubuntu-latest
    steps:
      - name: Detect Drift
        run: |
          terraform plan -detailed-exitcode || \
          gh pr create --title "Drift Alignment" \
          --body "Auto-generated PR aligning code to infrastructure"
Enter fullscreen mode Exit fullscreen mode

This maintains infrastructure-as-code principles while acknowledging reality through proper review processes.

Common Drift Sources Teams Miss

Auto-Scaling Policies create expected drift that should not trigger alerts. Configure lifecycle ignore rules:

resource "aws_autoscaling_group" "app" {
  desired_capacity = 10

  lifecycle {
    ignore_changes = [
      desired_capacity,  # Auto-scaling adjusts this
      target_group_arns  # Load balancer manages this
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Cost Optimization Tools like AWS Trusted Advisor or third-party services modify resources outside Terraform. Someone enables S3 Intelligent-Tiering to save money. Drift detector flags it as unauthorized change.

Solution? Either import cost-tool changes into Terraform or exclude those specific attributes from drift monitoring.

Disaster Recovery Procedures often require manual interventions. Failover to backup region happens automatically, creating resources Terraform did not provision. After recovery, drift exists between primary and DR environments.

Document DR drift as expected, implement automated state synchronization post-recovery.

Tool Comparison for 2025

Terraform Cloud/Enterprise offers native drift detection at $0.00014 per resource per hour beyond 500 free resources. For infrastructure with 2,000 resources, expect roughly $105 monthly.

Driftctl (open-source) scans cloud resources comparing against Terraform state, supports AWS/Azure/GCP/GitHub:

# Install driftctl
brew install driftctl

# Scan AWS infrastructure
driftctl scan --from tfstate+s3://mybucket/terraform.tfstate

# Generate report
driftctl scan --output json > drift-report.json
Enter fullscreen mode Exit fullscreen mode

Spacelift provides advanced features including automatic remediation, detailed drift analytics, and webhook integrations. Pricing starts around $50 monthly per user.

ControlMonkey focuses on shift-left approach, detecting drift during development before production deployment.

Comparison Table:

Tool Cost Best For Auto-Remediation
Terraform Cloud $0.00014/resource/hour Teams already on TF Cloud Yes
Driftctl Free (OSS) Multi-cloud, budget-conscious No
Spacelift ~$50/user/month Enterprise, complex workflows Yes
ControlMonkey Custom pricing Proactive drift prevention Yes

The Compliance Angle Nobody Emphasizes

Security and compliance frameworks like SOC 2, ISO 27001, HIPAA require documented change management. Infrastructure drift creates compliance violations when changes happen outside documented processes.

Auditors ask: "How do you ensure production infrastructure matches approved configurations?" Answering "We run terraform plan sometimes" fails audits.

Continuous drift detection with automated alerts provides audit trails showing:

  • When drift occurred
  • What changed specifically
  • Who received notifications
  • How quickly remediation happened
  • Whether changes got approved retroactively

Some industries like financial services and healthcare cannot tolerate infrastructure drift. Automated detection becomes regulatory requirement, not just operational best practice.

Making Drift Detection Stick Long-Term

Technology solves half the problem. Culture solves the rest.

Implement GitOps where main branch represents production reality. All infrastructure changes require pull requests. Manual console changes trigger immediate alerts requiring justification.

Create runbooks for common drift scenarios:

  • "Security group opened during incident" → Close immediately, file post-mortem ticket
  • "Instance type changed for performance" → Create optimization task, schedule proper implementation
  • "Resource manually deleted" → Investigate why, restore or remove from code

Monthly drift reviews catch patterns. Maybe developers constantly adjust compute resources because initial sizing was wrong. Fix root cause rather than constantly reverting drift.

Gamify it. Track "zero drift days" for each team. Celebrate milestones. Sounds silly but competitive engineers will work harder to avoid breaking streaks.


Critical Takeaways:

  1. Single database instance drift costs $6,300+ annually in preventable expenses
  2. Terraform plan -detailed-exitcode returns exit code 2 when drift exists, enabling automated detection
  3. Scan critical infrastructure every 15-30 minutes, non-critical resources hourly or daily
  4. Reconciliation reverts infrastructure to code; code alignment updates code to match reality
  5. Use lifecycle ignore_changes for expected drift from auto-scaling and cost-optimization tools
  6. Driftctl provides free open-source scanning across AWS, Azure, GCP, GitHub
  7. Terraform Cloud charges $0.00014 per resource hourly beyond 500 free resources
  8. Security-related drift requires immediate reconciliation without waiting for approval workflows
  9. Implement pull request workflows for code alignment maintaining infrastructure-as-code principles
  10. Compliance frameworks like SOC 2 and ISO 27001 require documented drift detection processes
  11. Orphaned resources from manual deletions continue generating costs until drift detection finds them
  12. GitOps workflows where main branch equals production reality reduce drift incidents by 60%+

Visual Content Suggestions:

  • Flowchart showing drift detection → notification → remediation workflow
  • Comparison chart of tool features (Terraform Cloud vs Driftctl vs Spacelift)
  • Cost impact graph showing drift accumulation over 12 months
  • Architecture diagram of multi-cloud drift monitoring setup

Expert Quote Attribution: Real-world implementation data comes from companies managing multi-cloud infrastructures documented in Spacelift and DZone case studies, showing 79% pipeline usage growth and $47K annual savings from drift detection.

Infrastructure drift is not going away. Cloud platforms encourage rapid iteration. Teams span time zones making coordination difficult. Incidents demand quick fixes. Accept drift will happen, build systems catching it within minutes not months, create processes preventing catastrophic accumulation. That's modern infrastructure management in 2025.

Top comments (0)