Skip to main content
RunBook Academy

← All labs in Terraform

Lab · intermediate · ~20 min

Lab: Using the terraform refresh Command

C · Simulation

Objectives

  • Use terraform refresh to update state from the real world
  • Use a refresh-only plan to detect drift
  • Distinguish between refresh and apply
  • Recognise the production risks of refreshing without investigation

Prerequisites

Objective

By the end of this lab, you will have:

  • Created a configuration with a file resource.
  • Simulated drift by manually editing the file.
  • Used terraform refresh to update the state.
  • Used a refresh-only plan to detect drift.
  • Verified the state is consistent with the real world.

Requirements

  • A Linux or macOS workstation with shell access.
  • The Terraform CLI 1.9.x or later installed.

Scenario

You have a configuration that creates a file. The file is managed by Terraform. An engineer manually edits the file without going through Terraform. The drift is intentional from the engineers perspective. The right response is to update the configuration to match the drift.

Tasks

Task 1: Create the working directory

mkdir -p ~/rb-refresh-lab
cd ~/rb-refresh-lab

Task 2: Initial configuration

Create main.tf:

terraform {
  required_version = ">= 1.9.0"
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "~> 2.5"
    }
  }
}

resource "local_file" "readme" {
  filename = "${path.module}/README.md"
  content  = "Initial content.\n"
}

Task 3: Initialise and apply

terraform init
terraform apply

Verify the file:

cat ~/rb-refresh-lab/README.md

Task 4: Simulate drift

An engineer manually edits the file to add a section:

cat > ~/rb-refresh-lab/README.md <<EOF
# Project README

This project is managed by Terraform.

## Manual section

This section was added by an engineer manually.
EOF

The drift is simulated. The state has the old content; the real world has the new content.

Task 5: Plan without refresh

terraform plan

The plan proposes to update the file to the configured content. The drift is detected.

Task 6: Refresh-only plan

terraform plan -refresh-only

The plan refreshes the state and detects the drift. The output shows the new attributes.

Task 7: Refresh the state

terraform refresh

The state is updated to match the real world. The file on disk is unchanged.

Task 8: Verify the state

terraform state show local_file.readme

The state has the new content (with the manual section).

Task 9: Plan after refresh

terraform plan

The plan is empty (or close to empty). The state matches the real world.

Task 10: Update the configuration to match the drift

The drift is intentional. Update the configuration to match:

resource "local_file" "readme" {
  filename = "${path.module}/README.md"
  content  = <<EOF
# Project README

This project is managed by Terraform.

## Manual section

This section was added by an engineer manually.
EOF
}

Run the plan:

terraform plan

The plan is empty.

Task 11: Verify the configuration

terraform plan

The plan is empty. The configuration matches the state matches the real world.

Validation

The lab is successful if:

  • The drift was simulated.
  • The refresh updated the state.
  • The plan was empty after the refresh.
  • The configuration was updated to match the drift.
  • The final plan was empty.

Expected Outcome

At the end of the lab:

+---------------------------------+
| ~/rb-refresh-lab/                  |
|   .terraform/                    |
|   .terraform.lock.hcl            |
|   README.md                       |
|   main.tf                        |
+---------------------------------+

The README.md file is updated to match the configuration. The state is consistent with the real world.

Cleanup

cd ~/rb-refresh-lab
terraform destroy
rm -rf .terraform .terraform.lock.hcl terraform.tfstate*

The main.tf is the only artefact worth keeping.

What You Learned

You learned the refresh workflow:

  1. Refresh updates state from the real world. It does not modify the real world.
  2. Refresh-only plan is the safest drift detection. It does not propose changes.
  3. Drift is information, not inconvenience. The decision is the engineer’s.
  4. Update the configuration to match the drift. The intentional drift is now part of the configuration.
  5. The plan is empty after the drift is accepted. The configuration matches the state matches the real world.

Deliverables

  • · A configuration with a file resource
  • · A simulated drift on the file
  • · A refresh-only plan that detects the drift
  • · A state updated by the refresh

Verification status

Last reviewed
2026-08-12
Executed end to end
not yet run on hardware

The commands and configuration here have been reviewed against the verified software versions, but nobody has run this lab start to finish on a system meeting its prerequisites. Treat the Expected Outcome as the intended result rather than an observed one, and keep the Cleanup section to hand.