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:
- Update the configuration to match the drift.
- 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 type | Configuration | Action |
|---|---|---|
| Intentional | Update configuration | Configuration now matches the drift |
| Accidental | Keep configuration | Apply reconciles the real world |
| Third-party (e.g. monitoring tool) | Add ignore_changes | State is updated; the configuration is unchanged |
| Unknown | Investigate | Do 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:
- Drift is information. A detected drift is a signal that something changed outside Terraform.
- The decision is the human review. The plan offers the drift; the engineer decides what to do.
- Intentional drift → update the configuration. The configuration should match the real world.
- Accidental drift → apply to reconcile. The configuration is correct; the real world is wrong.
- Auto-remediation is an antipattern. The drift may be intentional or accidental; the engineer must decide.