Drift Detection: Refresh, Plan Diffs & Out-of-Band Changes
Queries live cloud APIs to update the state file with actual runtime attributes.
Occurs when someone manually modifies firewalls, tags, or sizes in the web console.
Running 'apply' rewrites out-of-band changes back to declared code specifications.
The Big Idea
In an ideal world, all changes flow strictly through git commits and pull requests. In reality, emergencies happen: a production outage occurs at 3:00 AM, and an on-call engineer opens port 22 in an AWS Security Group or scales an ECS service directly from the cloud console.
This discrepancy is called Configuration Drift. The state file records what was applied yesterday, but the real cloud has mutated out-of-band. If left unchecked, drift leads to catastrophic silent bugs during subsequent deployments.
During every terraform plan, Terraform automatically executes a refresh phase in memory. It queries the live cloud provider APIs, compares the live reality against the state file, and then compares both against your HCL code. It flags differences as updates-in-place, giving you complete power to either overwrite the drift or codify it into your repository.
Jargon Buster: Plain-English Translations
- Configuration Drift: The delta between the desired infrastructure state declared in code and the actual live runtime state in the cloud.
- Out-of-Band Change: Any mutation performed outside of the Terraform workflow, such as web console edits or direct CLI commands.
- Reconciliation: The process of bringing live cloud resources back into strict compliance with the configuration code.
- Speculative Refresh: In-memory synchronization performed during 'terraform plan' without writing changes to the state file until applied.
Detecting and Resolving Drift with Plan Only
# 1. Speculative drift check without modifying state
terraform plan -refresh-only
# Sample output showing detected out-of-band console change:
# Note: Objects have changed outside of Terraform
# ~ resource "aws_security_group" "web_firewall" {
# ~ description = "Production Web Access" -> "Temporary SSH access by admin"
# }
# 2. To accept the out-of-band changes into your state file:
terraform apply -refresh-only
# 3. Or to FORCE reality back to match your HCL code:
# (Overwrites the manual console change and restores original desired state)
terraform apply
Beginner Traps & Gotchas
1. Running 'terraform refresh' blindly without reviewing a plan
The Gotcha: Running deprecated standalone refresh commands and accidentally syncing unwanted rogue changes into state.
The Fix: Always use the modern 'terraform plan -refresh-only' and 'terraform apply -refresh-only' workflow introduced in Terraform 0.15+.
2. Blaming Terraform when manually edited resources get reverted
The Gotcha: Wondering why an emergency console rule disappeared during the next automated deployment.
The Fix: Terraform will always enforce declarative code. If a manual fix is permanent, immediately backport it into your .tf code.