- Drift breaks the guarantees provided by IaC: reproducibility, auditability, and safe automation.
- Detecting drift early prevents unexpected infrastructure changes and outages.
- Choosing the right remediation keeps your Terraform configuration, state, and real resources aligned.
- You author Terraform configuration files that describe your desired infrastructure.
- Running Terraform records known resources and their attributes in the state file.
- Terraform then creates or updates real resources in the provider (for example, VMs).
- Desired configuration = Terraform configuration files
- State = Terraform state file
- Real world = Provider-managed resources
Imagine a simple configuration that defines two web servers. One is intended to have two CPUs and moderate memory; the other, one CPU and a lot of memory. After you apply the configuration, the configuration, the state, and the real cloud resources all align.
Drift scenario
If someone or something modifies a resource outside Terraform (for example, a colleague in the cloud console, a maintenance script, or an automated pipeline), the real resource can change without Terraform updating either the state file or your configuration. That mismatch is state drift: state ≠ real world.

- Real-world VM attributes no longer match Terraform’s state file.
- The Terraform configuration files still express the original desired values.
- Terraform’s state remains stale until a refresh occurs.
terraform plan is designed to detect.
How Terraform detects drift
- When you run
terraform plan, Terraform first refreshes the state by querying the provider for current attributes of managed resources. - It compares the refreshed state against the configuration you’ve authored.
- Any differences that require action will be shown in the plan output as proposed changes.
- Revert the external change (make real resources match your configuration)
- Keep the configuration as the source of truth.
- Use Terraform to change the real resource back to your desired values.
apply, Terraform calls the provider APIs to modify the real resource and then updates the state file so configuration, state, and reality match again.
- Accept the external change (make Terraform state and configuration reflect the new real-world state)
- If the external change was intentional and should become the desired state, update Terraform’s recorded state and then your configuration.
- Use
terraform apply -refresh-onlyto refresh the state from the provider and write those values into the state file without changing infrastructure.
terraform plan refreshes the state from the provider and compares it to your configuration. Use terraform apply -refresh-only to update state without making infrastructure changes when you want Terraform to adopt external updates.- Reverting external changes with
terraform applyensures the configuration remains the single source of truth. - Accepting external changes with
-refresh-onlywrites the provider state into Terraform’s state file; follow this with configuration updates so IaC stays authoritative. - Enforce change control: restrict direct console edits via IAM, require PRs, or centralize changes through a CI/CD pipeline that runs Terraform.
- Consider state locking (backends like S3 + DynamoDB, or remote backends) to prevent concurrent modifications to state.
Avoid relying on
-refresh-only as a permanent workaround. Prefer workflows where all changes go through Terraform so configuration, state, and real resources remain consistent and auditable.- Terraform state drift happens when real-world resources diverge from the state file and configuration.
terraform plandetects drift by refreshing state and comparing it to configuration.- To revert drift, run
terraform applyto make real resources match the configuration. - To accept drift, run
terraform apply -refresh-only, then update your configuration and apply.
- Terraform CLI Docs — plan
- Terraform CLI Docs — apply
- Terraform State Documentation
- Best practices for Terraform state management