What Is Terraform Refresh?
Terraform's state file is a snapshot of your infrastructure at the time of the last apply. But the real world keeps changing — someone modifies a security group in the AWS console, an auto-scaling group replaces an instance, or a manual CLI command changes a tag.
Terraform refresh reads the current real state of every resource in the state file from the cloud provider's API and updates the state file to match what actually exists. It is how Terraform syncs its memory with reality before deciding what changes to make.
In Terraform 1.0 and later, refresh happens automatically at the start of every terraform plan and terraform apply. You rarely need to run it manually.
+------------------------------------------+| terraform.tfstate (last apply) || security_group.web: || ingress port 443: 0.0.0.0/0 |+------------------------------------------+ | v (terraform refresh)+------------------------------------------+| Read real AWS resource via API || security_group.web: || ingress port 443: 0.0.0.0/0 || ingress port 22: 0.0.0.0/0 <- NEW || (someone added this in the console) |+------------------------------------------+ | v+------------------------------------------+| Updated terraform.tfstate || security_group.web: || ingress port 443: 0.0.0.0/0 || ingress port 22: 0.0.0.0/0 <- added || State now reflects reality |+------------------------------------------+How Refresh Fits Into Modern Terraform
# terraform plan already refreshes state automatically# It reads real infrastructure before calculating the diffterraform plan# Refreshing state... aws_instance.web# Refreshing state... aws_s3_bucket.assets# Refreshing state... aws_security_group.web# (then shows the plan) # Skip refresh if you know nothing changed externally (faster for large configs)terraform plan -refresh=false # Refresh state and show what drifted — WITHOUT making any infrastructure changesterraform apply -refresh-only# This updates your state file to match reality# It does NOT modify any real infrastructure# Useful for acknowledging manual changes you want to keep # Preview what refresh-only would change before committingterraform plan -refresh-onlyWhen to Use apply -refresh-only
The terraform apply -refresh-only command is the modern replacement for the old standalone terraform refresh command (which is deprecated). Use it when:
- Someone made a manual change in the console that you want to keep — refresh-only updates state to accept it without reverting it
- Your state file is out of sync with reality and you want to resync without making infrastructure changes
- You are debugging drift and want to see what changed before deciding what to do
# Scenario: an engineer added a tag manually in the AWS console# You want to accept this change without reverting it terraform plan -refresh-only# ~ aws_instance.web will be updated in state# ~ tags["TemporaryFix"] = null -> "incident-24-resolved"# Would update Terraform state to reflect these changes.# Note: this plan does not change any real infrastructure. terraform apply -refresh-only# State updated. No infrastructure was changed.# The manual tag is now recorded in state.The Deprecated terraform refresh Command
# This command still exists but is deprecated in Terraform 1.x# Do not use it in new workflowsterraform refresh# Deprecated: use terraform apply -refresh-only insteadDisabling Refresh for Speed
For large configurations with hundreds of resources, the refresh step can take minutes — each resource requires an API call to the cloud provider. If you are confident nothing has changed externally, skip refresh:
# Skip refresh — plan uses state file as-is without checking real infrastructure# Only use this when you are certain no external changes have been madeterraform plan -refresh=falseterraform apply -refresh=falseTroubleshooting Refresh
| Situation | What It Means | What to Do |
|---|---|---|
| Plan shows unexpected changes after refresh | State was out of sync — someone changed a resource externally | Review the changes — revert them with apply, or accept them with apply -refresh-only |
| Refresh is very slow | Large number of resources, each requires an API call | Use -refresh=false if you trust nothing changed externally |
| Resource shows as deleted after refresh | Resource was manually deleted in the console | Remove from state with terraform state rm or recreate with terraform apply |
Error: Inconsistent dependency lock file |
Lock file mismatch | Run terraform init -upgrade |
PLACEMENT PRO TIP**Tip:** Run `terraform plan -refresh-only` as a scheduled job (daily or weekly) in CI/CD to detect drift automatically. If the plan shows any changes, alert the team that someone has modified infrastructure outside of Terraform.