Terraform State Refresh: Reconciling State Drift and Managing Infrastructure Reality

Terraform relies on a state file to manage the infrastructure it controls. This state file acts as a source of truth, mapping real-world resources to the configurations defined in Terraform. By maintaining this state, Terraform can determine what changes need to be applied without recreating resources unnecessarily. Refreshing the workspace's state updates Terraform's knowledge of the infrastructure with the current state of resources as reported by the configured providers.

State drift is a core reason refresh exists. State drift occurs when the actual infrastructure differs from what Terraform expects. This can happen when resources are modified directly in the infrastructure interfaces, through PowerShell, CLI, third-party software APIs, or scripts. Changes can be made directly in the infrastructure interfaces, through PowerShell, CLI, etc and this can be what is called state drift. Drift can lead to unexpected behaviours when new changes are applied via Terraform. If your Terraform state drifts because changes are made outside of your Terraform configuration, it's important to make sure you refresh your state file to check the status of resources and update it accordingly so you can move forward with future changes.

What Terraform Refresh Actually Does

At its core, terraform refresh reconciles Terraform state with the actual infrastructure. It queries your cloud provider APIs to get the current state of resources and updates the state to match reality.

Terraform manages the infrastructure resources and deployment using the state file. By running the refresh command, you can update the state file with the actual infrastructure configuration. Let’s say that the resources managed by the Terraform code are sometimes modified using a console, CLI, third-party software APIs, or scripts.

The process is methodical:

  • Terraform reads the current state file
  • For each resource in state, it queries the provider API
  • It compares the actual infrastructure attributes with stored state
  • The state file is updated to reflect real-world values

Terraform refreshes its state by querying the infrastructure to detect any changes made outside of Terraform (manual changes, updates by other tools, etc.). This process ensures that the Terraform state file reflects the current state of the infrastructure.

Terraform tracks information about the resources it manages in your workspace's state file. When you apply changes to your resources with Terraform, it creates an execution plan by comparing your workspace's configuration to its current state. Refreshing your workspace's state updates Terraform's knowledge of your infrastructure with the current state of your resources as reported by the configured providers.

Implicit Refresh Behavior in Plan and Apply

Terraform plan and apply operations run an implicit in-memory refresh as part of their operations, reconciling any drift from your workspace's state before creating a plan for your infrastructure changes.

Does Terraform plan refresh the state? Yes, Terraform refreshes the state and updates the state file with the most recent resource configuration of the current infrastructure. It ensures that the plan reflects the current state rather than the desired state before any changes are made.

You can also plan and apply updates to your state file without making modifications to your infrastructure using the -refresh-only flag.

The implicit refresh means that a normal plan already compares configuration to current state. The explicit refresh-only mode lets you update state without any changes to real resources.

The Deprecated Standalone Refresh Command

The terraform refresh command reads the current settings from all managed remote objects and updates the Terraform state to match. This command is deprecated. Instead, add the -refresh-only flag to terraform apply and terraform plan commands.

This does not modify your real remote objects, but it modifies the Terraform state.

As of Terraform version v0.15.4, the terraform refresh command was deprecated because its default behavior could be deemed unsafe if you have misconfigured credentials for any of your providers.

Why was standalone refresh deprecated? The standalone terraform refresh command was deprecated because it modifies state without showing you what changed.

Usage: terraform refresh [options]

This command is effectively an alias for the following command:

terraform apply -refresh-only -auto-approve

Consequently, it supports all of the same options as terraform apply except that it does not accept a saved plan file, it doesn't allow selecting a planning mode other than "refresh only", and -auto-approve is always enabled.

Automatically applying the effect of a refresh is risky.

The standalone refresh command was deprecated in Terraform 0.15.4 but still works in practice.

Example syntax that remains functional:

terraform refresh

terraform refresh -var-file="production.tfvars"

terraform refresh -target=aws_instance.web_server

All use cases of the Terraform refresh discussed here work similarly in OpenTofu, the open-source Terraform alternative. However, to keep it simple and familiar for DevOps engineers, Terraform refresh is used as a catch-all term throughout.

Modern Refresh with -refresh-only

Modern Terraform uses the -refresh-only flag with plan and apply.

Recommended approach to view what would change:

terraform plan -refresh-only

Apply refresh changes to state:

terraform apply -refresh-only

You can also run a refresh without making infrastructure changes using:

terraform apply -refresh-only

This is the replacement for the deprecated standalone command.

The -refresh-only flag lets you plan and apply updates to your state file without making modifications to your infrastructure. It provides visibility before state is mutated, which the old command lacked.

How to Apply Without Refreshing State

Sometimes you want to apply a plan based on existing state without re-querying providers.

You can apply the Terraform refresh by running the terraform apply -refresh=false command. It skips the refresh and applies the plan based on the existing state.

This is useful when you know the state is accurate and want to avoid API calls or when provider credentials are problematic.

Refresh vs Import vs Plan

Understanding the boundaries between refresh, import, and plan prevents misuse.

Operation What it does Modifies real infrastructure? Modifies state file?
terraform refresh Reads current settings from remote objects and updates state to match No Yes
terraform plan -refresh-only Shows differences between state and reality without applying No No, until apply
terraform apply -refresh-only Updates state to match reality without changing resources No Yes
terraform import Associates existing resource with Terraform resource block No Yes
terraform apply Creates execution plan and applies changes Yes Yes

Terraform’s refresh command updates the state file by checking the actual infrastructure to reflect any changes made outside Terraform (e.g., manually via the AWS Console). It doesn’t create or modify resources, only syncs the state with the real world.

Terraform’s import command is used to bring existing resources into Terraform’s management. It associates an existing infrastructure resource with a Terraform resource block, allowing Terraform to manage it going forward. It updates the state file but doesn’t modify the resource itself.

Refresh syncs known resources. Import adopts unknown resources.

When to Use Refresh

Use refresh when:
- Infrastructure was modified outside Terraform via console, CLI, API, or scripts
- State drift is suspected before making new changes
- Provider data has changed and state needs to be realigned
- You need to verify current attribute values before planning

Terraform can refresh your state file; this was previously done with the terraform refresh command. In this blog post, we will explore how Terraform handles state refresh, including the -refresh-only flag, and the key considerations when updating your Terraform state file.

Key considerations include credential correctness, because refresh queries providers. As noted, the deprecation was partly due to unsafe default behavior if you have misconfigured credentials for any of your providers.

Practical Workflow

A safe workflow for dealing with drift is:

  • Run terraform plan -refresh-only to see what drift exists
  • Review the output for attribute differences
  • Run terraform apply -refresh-only to sync state if no changes to resources are desired
  • Then run a normal terraform plan to see configuration-driven changes on top of accurate state

This workflow gives visibility that the deprecated standalone refresh lacked.

You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects.

Conclusion

Terraform state refresh is the mechanism that keeps Terraform's understanding of infrastructure aligned with reality. The command reconciles Terraform state with the actual infrastructure by querying provider APIs, comparing actual attributes with stored state, and updating the state file to reflect real-world values. Terraform plan and apply already perform an implicit in-memory refresh before planning, ensuring plans are based on current reality.

The standalone terraform refresh command was deprecated in Terraform v0.15.4 because it modifies state without showing you what changed and can be unsafe with misconfigured credentials. Modern practice replaces it with terraform plan -refresh-only for inspection and terraform apply -refresh-only for state synchronization without modifying real resources.

Refresh differs from import. Refresh updates state for resources already managed to reflect external changes. Import brings externally created resources under Terraform management. Neither creates or modifies real infrastructure; they only affect state.

Using -refresh-only provides a safe, visible way to address state drift caused by manual console edits, CLI changes, or third-party tools. Keeping state accurate ensures future plans and applies behave predictably and do not recreate or overwrite resources unintentionally.

Sources

  1. Env0 Blog
  2. OneUptime Blog
  3. Dev.to Techielass
  4. Hashicorp CLI Commands Refresh
  5. Hashicorp Tutorial State Refresh

Related Posts