Terraform Refresh Command: Exact Behavior and Implementation Details

terraform refresh updates the state file to match real-world infrastructure without making any changes to the actual resources.

When working with the HashiCorp Terraform repository, understanding the exact behavior of the terraform refresh command is essential for safe infrastructure management. This command performs a read-only synchronization that reconciles your Terraform state with the actual state of your cloud resources by querying providers and updating local state representation.

What Does Terraform Refresh Do?

The terraform refresh command is a read-only operation that queries your infrastructure providers to determine the current state of managed resources. It then updates the local or remote state file to reflect reality, ensuring that subsequent terraform plan or terraform apply operations work with accurate data. Importantly, this command never modifies the actual infrastructure—it only updates the state representation stored in your backend.

Step-by-Step Execution Flow of Terraform Refresh

The implementation in internal/command/refresh.go follows a precise nine-step workflow:

1. CLI Argument Parsing

The command begins by parsing global view flags and refresh-specific options through ParseRefresh in internal/command/arguments/refresh.go. This function handles flags like -input, -lock, -target, and -parallelism, storing them in the operation arguments structure.

2. View Configuration

Based on the output format (human or JSON), the command initializes the appropriate view via views.NewRefresh in internal/command/views/refresh.go. This determines how progress and results will be rendered to the user.

3. Backend Preparation

The PrepareBackend method loads the configured backend for the workspace, applying any state-related CLI arguments. This step establishes whether the operation will use local state or a remote backend like Terraform Cloud.

4. Operation Request Creation

The command constructs a backendrun.Operation with Type: backendrun.OperationTypeRefresh (defined in internal/backend/backendrun/operation_type.go). This request encapsulates the configuration loader, target resources, hooks, and view interface.

5. Backend Execution

The backend receives the operation request. For the built-in local backend (internal/backend/local/backend.go), the Local.Operation method selects b.opRefresh when it detects OperationTypeRefresh.

6. Resource Refresh Logic

The opRefresh function iterates through every managed resource, querying the provider for current attributes. It writes any detected differences back to the in-memory state representation without modifying remote resources.

7. State Persistence

Once refresh completes, the state manager writes the updated snapshot to the state file, or to the -state-out location if specified via CLI arguments.

8. Output Rendering

The view layer prints any new output values through RefreshHuman.Outputs or RefreshJSON.Outputs, depending on the selected format.

9. Exit Status

The command returns the operation's exit status via op.Result.ExitStatus(), completing the workflow.

Practical Terraform Refresh Examples

Basic Refresh with Human Output

terraform refresh

This executes the full nine-step workflow, displaying human-readable logs and any output values.

JSON Output for Automation

terraform refresh -json

Uses the RefreshJSON view (internal/command/views/refresh.go) to emit streaming JSON suitable for CI/CD pipelines and automated parsing.

Targeted Resource Refresh

terraform refresh -target=aws_instance.example

The target list is stored in args.Operation.Targets and passed to the operation request, restricting the refresh to only the specified resource and its dependencies.

Custom State File Paths

terraform refresh -state=pre-prod.tfstate -state-out=pre-prod-refreshed.tfstate

Legacy flags -state and -state-out are accepted for the local backend, propagated through PrepareBackend and StatePaths to control input and output state file locations.

Key Source Files and Implementation Details

File Role in Refresh Workflow
internal/command/refresh.go Main command implementation – parses arguments, builds operation, executes workflow
internal/command/arguments/refresh.go CLI flag definition and parsing via ParseRefresh
internal/command/views/refresh.go View interface and concrete Human/JSON implementations via NewRefresh
internal/backend/backendrun/operation_type.go Enum defining OperationTypeRefresh
internal/backend/local/backend.go Local backend implementation; selects opRefresh via Local.Operation
internal/backend/local/backend_refresh_test.go Tests verifying state updates without resource changes
internal/cloud/backend_refresh_test.go Cloud backend refresh tests for remote state synchronization

These files collectively implement the read-only synchronization behavior of terraform refresh across local and remote backends.

Summary

  • terraform refresh performs a read-only update of the state file to match real-world infrastructure.
  • The command executes a nine-step workflow from CLI parsing through state persistence.
  • No infrastructure changes occur during refresh; only the state representation is modified.
  • The implementation spans internal/command/refresh.go, internal/backend/local/backend.go, and related view/argument files.
  • Use targeted refresh (-target) or JSON output (-json) for specific automation needs.

Frequently Asked Questions

What is the difference between terraform refresh and terraform plan?

terraform refresh updates the state file to match real infrastructure without showing planned changes or modifying resources. terraform plan compares the current configuration against the refreshed state and displays proposed changes without applying them. Run terraform refresh first to ensure accurate planning.

Does terraform refresh modify my actual infrastructure?

No. According to the implementation in internal/backend/local/backend.go, the opRefresh function only queries providers for current resource attributes and updates the in-memory state representation. The command performs a read-only synchronization that persists only to the state file, never to the actual cloud resources.

When should I use terraform refresh versus terraform apply -refresh-only?

Use terraform refresh (or terraform apply -refresh-only in Terraform 0.15+) when you need to update the state file to match manual changes made outside of Terraform. The -refresh-only apply mode uses the same OperationTypeRefresh type internally but provides the safety net of Terraform's standard apply workflow. Both update only the state without resource modifications.

Can I refresh only specific resources?

Yes. Use the -target flag to specify which resources to refresh. The ParseRefresh function in internal/command/arguments/refresh.go handles this flag, storing targets in args.Operation.Targets. The backend then limits the refresh operation to only those resources and their dependencies, improving performance in large environments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →