Skip to main content
RunBook Academy

← All labs in Terraform

Lab · intermediate · ~25 min

Lab: Drift Detection and Remediation

C · Simulation

Objectives

  • Create a configuration with two files
  • Simulate drift by manually editing one file
  • Detect the drift with `terraform plan`
  • Decide the correct remediation: accept drift or reconcile
  • Apply the chosen remediation and verify the result

Prerequisites

Objective

By the end of this lab, you will have:

  • Created a Terraform configuration with two files.
  • Simulated drift by manually editing one file.
  • Detected the drift with terraform plan.
  • Made the correct remediation decision.
  • Applied the chosen remediation and verified the result.

The lab focuses on the decision: drift is detected; what is the right action?

Architecture

A configuration with two resources and a simulated drift:

+-----------------------------+
| Terraform                   |
|       ↓                     |
| local_file.greeting         |
| local_file.readme           |
|       ↓                     |
| ~/rb-drift-lab/             |
|   ├── greeting.txt          |
|   └── readme.txt            |
+-----------------------------+

The drift is on the greeting.txt file. The configuration says the content is “Hello!”. The drift is the file content changed to “Hello, world!”.

Requirements

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

Scenario

You maintain a Terraform configuration. The configuration manages two files. A colleague manually changes one of the files. The drift is real. You must decide what to do.

Tasks

Task 1: Create the working directory

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

Task 2: Write the configuration

Create main.tf:

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

resource "local_file" "greeting" {
  filename = "${path.module}/greeting.txt"
  content  = "Hello!\n"
}

resource "local_file" "readme" {
  filename = "${path.module}/readme.txt"
  content  = "This is a readme file.\n"
}

Task 3: Initialise and apply

terraform init
terraform apply

Verify the files:

ls -la ~/rb-drift-lab
cat ~/rb-drift-lab/greeting.txt
cat ~/rb-drift-lab/readme.txt

Task 4: Verify the empty plan

terraform plan

Expected:

No changes. Your infrastructure matches the configuration.

The plan is empty.

Task 5: Simulate drift

The colleague manually edits greeting.txt:

echo "Hello, world!" > ~/rb-drift-lab/greeting.txt

Verify the change:

cat ~/rb-drift-lab/greeting.txt

The file is now “Hello, world!” The state still has “Hello!”.

Task 6: Detect the drift

terraform plan

The plan shows the drift:

# local_file.greeting will be updated in-place
~ resource "local_file" "greeting" {
    ~ content             = "Hello!\n" -> "Hello, world!\n"
    ~ content_base64      = "SGVsbG8hCg==" -> "SGVsbG8sIHdvcmxkIQo="
    # (5 unchanged attributes hidden)
  }

Plan: 0 to add, 1 to change, 0 to destroy.

The plan proposes to update the file to the configuration value. The drift is detected.

Question 1: Is this drift intentional or accidental?

Answer

The drift is simulated for the lab. In production, the answer depends on the operators intent:

  • Drift is intentional if the colleagues change was intended (e.g. a new greeting that should be permanent).
  • Drift is accidental if the colleagues change was a mistake (e.g. a temporary edit that was not reverted).

The lab assumes the drift is accidental — the colleague should not have changed the file outside Terraform.

Task 7: Investigate the drift

Before applying, investigate:

git status ~/rb-drift-lab/greeting.txt  # if the directory is in git
terraform state show local_file.greeting

The state has the original value. The drift is on the real world.

# Check the files modification time
stat ~/rb-drift-lab/greeting.txt

The file was modified recently. The drift is fresh.

Task 8: Reconcile the drift

The drift is accidental. The configuration is correct. The apply reconciles the real world to the configuration.

terraform apply

The plan is recomputed. The apply executes the plan.

Verify:

cat ~/rb-drift-lab/greeting.txt

Expected:

Hello!

The file is restored to the configuration value.

Task 9: Scenario B — Intentional drift

Now simulate intentional drift. The colleague makes a change that should be permanent.

echo "Hello, world!" > ~/rb-drift-lab/greeting.txt

Detect the drift:

terraform plan

The plan shows the drift.

Question 2: What is the correct remediation?

Answer

The drift is intentional. The configuration should be updated to match the real world. The “apply” would reconcile the real world to the configuration; the correct action is to update the configuration.

The remediation:

  1. Update the configuration to match the drift.
  2. Apply. The plan is now empty.

Update the configuration:

resource "local_file" "greeting" {
  filename = "${path.module}/greeting.txt"
  content  = "Hello, world!\n"
}

Run the plan:

terraform plan

Expected:

No changes. Your infrastructure matches the configuration.

The configuration matches the state matches the real world.

Task 10: Verify the configuration

terraform show

The output shows the attributes. The content is now “Hello, world!\n”.

Task 11: Decision table

A summary of the decision workflow:

Drift typeConfigurationAction
IntentionalUpdate configurationConfiguration now matches the drift
AccidentalKeep configurationApply reconciles the real world
Third-party (e.g. monitoring tool)Add ignore_changesState is updated; the configuration is unchanged
UnknownInvestigateDo not apply until the cause is known

Validation

The lab is successful if:

  • The drift was detected by the plan.
  • The first drift was reconciled correctly.
  • The second drift was accepted into the configuration.
  • The plan is empty after each remediation.

Expected Outcome

At the end of the lab:

+---------------------------------+
| ~/rb-drift-lab/                    |
|   .terraform/                    |
|   .terraform.lock.hcl            |
|   greeting.txt    "Hello, world!" |
|   main.tf                        |
|   readme.txt                     |
+---------------------------------+

The greeting.txt file contains the second-drift value. The state and the configuration match.

Cleanup

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

What You Learned

You learned the drift workflow:

  1. Drift is information. A detected drift is a signal that something changed outside Terraform.
  2. The decision is the human review. The plan offers the drift; the engineer decides what to do.
  3. Intentional drift → update the configuration. The configuration should match the real world.
  4. Accidental drift → apply to reconcile. The configuration is correct; the real world is wrong.
  5. Auto-remediation is an antipattern. The drift may be intentional or accidental; the engineer must decide.

Deliverables

  • · A configuration with two files
  • · A simulated drift scenario
  • · A documented decision: accept or reconcile
  • · A applied remediation

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.