Terraform Refresh State: What It Does and When to Use It

Chafik Belhaoues

Terraform refresh state is an operation that synchronizes Terraform's internal representation with the actual state of the infrastructure. Without this synchronization, Terraform may suggest changes based on outdated data, leading to unpredictable deployments. In this article, we'll break down how refresh works, how it differs from other commands, and when to use it to detect drift and prevent problems.

What Is Terraform State and Why Does It Matter?

Terraform state is a JSON file that serves as a mapping between configuration files and the actual infrastructure resources they create. It stores metadata for each resource, its dependencies, and its current attributes. Thanks to the state, Terraform understands:

  • Which resources already exist
  • What needs to be changed in the next apply
  • Which resources to create or delete

The Terraform update-state operation updates this file to reflect reality. Without an up-to-date state, Terraform works unthinkingly: it may try to create an existing resource or delete one that has been changed outside of Terraform. Therefore, keeping the state up to date is the basis for reliable infrastructure management. For teamwork with the state, we recommend using Brainboard, which visualizes the state and architecture in a single interface.

What Does Terraform Refresh State Do?

Terraform syncs the state file with the actual infrastructure during the refresh operation. Terraform accesses the APIs of cloud providers (AWS, Azure, GCP, and others) and requests the current state of each managed resource. The data received is written to the state file.

Key point: refresh does not change the actual infrastructure. It only updates Terraform's internal record. If someone manually changes the security group settings in the AWS console, a refresh will record this change in the state, but will not roll it back.

Historically, refresh was a separate command, terraform refresh. Now it is integrated as the first step by default in Terraform plan and Terraform apply. This means that every time you plan or apply, Terraform automatically checks the state against reality before calculating the changes.

Terraform Refresh vs. Other State Commands

To avoid confusion, let's break down how refresh differs from other common state operations.

Terraform Refresh vs. Terraform Apply

Refresh only updates the state file, aligning it with reality. Apply, on the other hand, changes the actual infrastructure to align it with the configuration. The terraform apply refresh command in the format terraform apply -refresh-only combines both approaches: it updates the state without changing resources. It lets you review the differences before writing. This is the recommended way to update the state safely.

Terraform Refresh vs. Terraform Init

terraform init initializes the working directory: it downloads providers and modules and configures the backend for storing the state. This command does not interact with the actual infrastructure and does not update the state. The Terraform reinitialization operation via multiple Terraform init commands may be necessary when changing the backend or updating providers. Still, it never synchronizes the state with live resources - this requires a refresh.

Terraform Refresh vs. Terraform State Reset

Resetting Terraform state means deleting or completely replacing the state file. This is a destructive operation: Terraform loses all information about existing resources and will attempt to recreate everything the next time it is run, which can lead to conflicts and duplication. Refresh, unlike reset, is a safe synchronization operation. Resetting the state should only be done in extreme cases and with a full understanding of the consequences.

When to Use Terraform Refresh State

There are several practical scenarios where the Terraform update command refresh is necessary or highly recommended:

  • After manual changes in the cloud console. If someone on the team has changed a resource via the AWS Console, Azure Portal, or GCP Console, the state no longer matches reality. Refresh will capture these changes.
  • When debugging unexpected plan output. If the Terraform plan shows unexpected changes, it may be due to an outdated state. Refresh will help identify discrepancies.
  • When connecting existing infrastructure. After a Terraform import, it is useful to refresh the state so that it contains the full attributes of the imported resources.
  • After a failed application. If the application is interrupted midway, the state may be partially updated. Refresh will bring it to a consistent state.
  • As part of regular drift detection. Scheduled automatic refresh helps identify unauthorized changes.

The Brainboard platform simplifies drift management by visualizing discrepancies between configuration and actual infrastructure.

How to Run Terraform Refresh Safely

Terraform update state via refresh requires caution, especially in command environments. Follow these recommendations:

  1. Make a backup of the state. Before any operation with state, perform a backup: cp terraform.tfstate terraform.tfstate.backup.
  2. Use terraform apply -refresh-only. Instead of the outdated Terraform refresh command, run Terraform apply -refresh-only. This allows you to view the state change plan before writing it.
  3. Use -target for incremental updates. When working with large state files, update specific resources: terraform apply -refresh-only -target=aws_instance.web.
  4. Use state locking. The -lock=true flag (enabled by default) prevents multiple team members from modifying the state simultaneously.
  5. Store state in a remote backend. Use S3, GCS, or Terraform Cloud to store state. This provides versioning, locking, and shared access.

Brainboard is suitable for secure state management in a team, providing centralized storage and visual control over infrastructure changes.

Common Issues and Troubleshooting

When working with Terraform refresh state, teams encounter typical issues:

  • Refresh shows resource deletion. The usual cause is insufficient IAM permissions: Terraform cannot read the resource via the API, so it considers it deleted. Check the provider's access rights.
  • State lock conflicts. In command environments, parallel operations cause a state lockerror. The solution is to wait for the current operation to complete or, as a last resort, execute Terraform force-unlock.
  • Timeouts on large infrastructures. Refreshing hundreds of resources requires multiple API calls. Use -target to update individual modules or increase the provider's timeouts.
  • State file corruption. If the state file is corrupted, restore it from a backup or remote backend. Do not attempt to edit JSON manually - use the Terraform state commands for safe operations.

When complex state issues arise, tools such as Brainboard help visualize the current state of the infrastructure and quickly find the cause of discrepancies.

FAQ

Is Terraform refresh deprecated?

The separate Terraform refresh command is considered deprecated as of version 0.15.4. The recommended replacement is terraform apply -refresh-only, which allows you to view state changes before they are written.

Does Terraform refresh change the real infrastructure?

No. Refresh only updates the state file. Real resources in the cloud remain untouched. Only Terraform applies infrastructure changes.

How often should I refresh Terraform state?

In a standard workflow, a separate refresh is not necessary - plan and apply it automatically. A manual refresh is useful after manual changes in the console or for regular drift detection.

Can I undo a Terraform refresh?

Yes, if you backed up the state before the refresh. Simply restore the previous state file. When using a remote backend with versioning, you can roll back to the previous version.

What happens if I delete the Terraform state file?

Terraform will lose information about all managed resources. The next time you apply, it will try to recreate everything, leading to duplicate errors. You can restore the connection using Terraform import, but this is a laborious process.