# Terraform Refresh Command: Exact Behavior and Implementation Details

> Understand the exact behavior of the terraform refresh command. Update your Terraform state file to match real-world infrastructure without altering resources.

- Repository: [HashiCorp/terraform](https://github.com/hashicorp/terraform)
- Tags: internals
- Published: 2026-02-20

---

**`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`](https://github.com/hashicorp/terraform/blob/main/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`](https://github.com/hashicorp/terraform/blob/main/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`](https://github.com/hashicorp/terraform/blob/main/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`](https://github.com/hashicorp/terraform/blob/main/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`](https://github.com/hashicorp/terraform/blob/main/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

```bash
terraform refresh

```

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

### JSON Output for Automation

```bash
terraform refresh -json

```

Uses the `RefreshJSON` view ([`internal/command/views/refresh.go`](https://github.com/hashicorp/terraform/blob/main/internal/command/views/refresh.go)) to emit streaming JSON suitable for CI/CD pipelines and automated parsing.

### Targeted Resource Refresh

```bash
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

```bash
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`](https://github.com/hashicorp/terraform/blob/main/internal/command/refresh.go) | Main command implementation – parses arguments, builds operation, executes workflow |
| [`internal/command/arguments/refresh.go`](https://github.com/hashicorp/terraform/blob/main/internal/command/arguments/refresh.go) | CLI flag definition and parsing via `ParseRefresh` |
| [`internal/command/views/refresh.go`](https://github.com/hashicorp/terraform/blob/main/internal/command/views/refresh.go) | View interface and concrete Human/JSON implementations via `NewRefresh` |
| [`internal/backend/backendrun/operation_type.go`](https://github.com/hashicorp/terraform/blob/main/internal/backend/backendrun/operation_type.go) | Enum defining `OperationTypeRefresh` |
| [`internal/backend/local/backend.go`](https://github.com/hashicorp/terraform/blob/main/internal/backend/local/backend.go) | Local backend implementation; selects `opRefresh` via `Local.Operation` |
| [`internal/backend/local/backend_refresh_test.go`](https://github.com/hashicorp/terraform/blob/main/internal/backend/local/backend_refresh_test.go) | Tests verifying state updates without resource changes |
| [`internal/cloud/backend_refresh_test.go`](https://github.com/hashicorp/terraform/blob/main/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`](https://github.com/hashicorp/terraform/blob/main/internal/command/refresh.go), [`internal/backend/local/backend.go`](https://github.com/hashicorp/terraform/blob/main/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`](https://github.com/hashicorp/terraform/blob/main/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`](https://github.com/hashicorp/terraform/blob/main/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.

```