- Drift = differences between your Terraform configuration, the recorded Terraform state, and the actual cloud resources.
- Left unresolved, drift can lead to unexpected resource changes, failed applies, or configuration confusion.
- Terraform provides commands to detect drift and options to either enforce the configuration or adopt the real-world change.
- You write Terraform configuration that declares resources (for example, several VMs with specific CPU and memory).
- You run
terraform apply. Terraform creates or updates resources and records their attributes in the state file (local or remote). - If someone or some process modifies resources directly in the cloud (manual edit, console change, autoscaling, or external automation), the real resources can diverge from the recorded state and your configuration. That divergence is state drift.
terraform plan, Terraform refreshes resource attributes (by default) to compare the real infrastructure against your configuration and state. If differences exist, terraform plan will show them as proposed changes.
- Default behavior:
terraform planrefreshes state and compares it to configuration. - Skip refresh:
terraform plan -refresh=falseavoids refreshing attributes (rarely recommended).
- Revert the change: Make the real infrastructure match your declared configuration.
- Accept the change: Update Terraform state (and configuration) to adopt the real-world values.
Conceptual flows (step-by-step)
-
Revert flow
terraform plandetects drift (plan shows changes that will be made to the real resources).terraform applyruns and updates the real infrastructure to match the configuration.- Terraform updates state; now configuration, state, and reality are aligned.
-
Accept (adopt) flow
terraform plandetects drift (plan shows differences).terraform apply -refresh-onlyupdates the state file to reflect reality without changing resources.- Update your Terraform configuration files (
.tf) to match the real-world values. - Run
terraform plan/applygoing forward to preserve consistency.
terraform plan refreshes resource attributes by default to detect drift. Use -refresh=false only when you intentionally want to skip that check (for example, in a controlled test where provider calls are undesirable).Use
terraform apply -refresh-only with care: it modifies the state to match the real world without changing any infrastructure. Only run it when you are certain the real-world changes should become the canonical state.- Make Terraform the single source of truth for infrastructure changes whenever possible.
- Limit manual console edits; prefer automation or changes via Terraform.
- Protect state with remote backends and state locking (e.g., S3 + DynamoDB lock, Terraform Cloud).
- Use CI pipelines to apply changes so modifications are auditable and repeatable.
- If manual changes are unavoidable, document and promptly reconcile by updating state and configuration.
- Terraform CLI documentation: https://www.terraform.io/cli
- State documentation: https://www.terraform.io/language/state
- State drift = mismatch between declared configuration, recorded Terraform state, and real-world resources.
terraform plandetects drift by refreshing resource attributes by default.- To revert drift: run
terraform applyso the real resources match your configuration. - To accept drift: run
terraform apply -refresh-onlyto update state, then update your configuration to reflect the real-world values.