TerraformXVII · Drift Detection and ReconciliationDrift
Refreshing State: Reducing Drift to Reality
What you'll learn
- Use terraform refresh to update state from the real world
- Use refresh-only plans to detect drift
- Recognise when refresh is the right tool
- Avoid the antipattern of auto-refresh on every apply
Prerequisites
Verified against Terraform CLI 1.9.x · OpenTofu 1.7.x · HCL 2.0 · bpg/proxmox provider 0.66+ · hashicorp/local provider 2.5+ · hashicorp/null provider 3.2+ · hashicorp/random provider 3.6+ · hashicorp/http provider 3.4+ · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · 2026-08-12
terraform refresh updates the state to match the real world.
It does not modify the real world. The refresh is the read
operation that makes the state accurate. The lesson teaches
the refresh command and the production patterns.
The refresh command
terraform refresh
The output:
aws_instance.web: Refreshing state... [id=i-0abc123def456789]
aws_security_group.web: Refreshing state... [id=sg-0abc123def456789]
Warning: One or more providers have changed version since the
state was last written.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
The refresh:
- Reads the current state.
- Asks the provider for the current attributes of every resource.
- Updates the state to match the real world.
- Does not modify the real world.
The output is “0 added, 0 changed, 0 destroyed” because the refresh did not modify the real world. The state was updated.
The refresh-only plan
A refresh-only plan is a plan that does not propose any changes. It only refreshes the state:
terraform plan -refresh-only
The output:
aws_instance.web: Refreshing state... [id=i-0abc123def456789]
aws_security_group.web: Refreshing state... [id=sg-0abc123def456789]
No changes. Your infrastructure matches the configuration.
Or:
aws_instance.web: Refreshing state... [id=i-0abc123def456789]
aws_instance.web: Attributes changed during refresh
+ tags["Environment"] = "production"
~ id = "i-0abc123def456789" -> "i-0abc123def456789"
Warning: Resource attributes changed during refresh
Terraform has updated the state in response to the refresh.
The output shows the drift. The state has been updated. The next plan will not propose to change the new attribute.
When to use refresh
Refresh is appropriate when:
- Detecting drift. The refresh-only plan is the safest way to detect drift.
- Recovering from a state error. A state that is missing attributes can be refreshed to repopulate.
- Verifying the state. The refresh confirms that the state is consistent with the real world.
Refresh is not appropriate when:
- Auto-remediating drift. A refresh followed by an apply is auto-remediation.
- Skipping plan review. The refresh does not replace plan review.
The refresh antipattern
A common antipattern is to refresh on every apply:
# Bad: implicit refresh on every apply
terraform apply # refreshes state, then applies
The implicit refresh is the source of a subtle bug: the refresh may update the state based on a transient real-world state. The apply then proposes to “reconcile” the state back to the configuration.
The fix is to use the -refresh=false flag:
terraform apply -refresh=false
The -refresh=false flag skips the refresh. The apply uses
the existing state. The plan must be reviewed.
The state locking
The refresh acquires the state lock:
# This will fail if the state is locked
terraform refresh
The lock prevents concurrent state mutations. The refresh is safe to run as long as the state is not locked.
The refresh in CI
A CI pipeline can use a refresh-only plan:
- run: terraform init
- run: terraform plan -refresh-only
The plan is uploaded as an artifact. The plan is reviewed. The plan is the audit trail.
What comes next
The next lesson is drift detection in production — the continuous workflow for detecting and remediating drift.
Verification
Knowledge check · 7 questions
Q1. What is configuration drift?
Q2. How is drift detected?
Q3. Drift should be auto-remediated without review.
Q4. How is drift resolved?
Q5. Which of the following are sources of drift? (Select all that apply.)
Q6. What is intentional drift?
Q7. A team runs refresh-only plans every hour. The plan always shows the same drift. What is the fix?
Passing score: 75%. Answers are checked in this browser.