Objective
By the end of this lab, you will have:
- Used lifecycle.prevent_destroy on a critical resource.
- Verified that the configuration cannot propose to destroy the resource.
- Recognised the production role of prevent_destroy.
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 critical file. The
file should never be destroyed by the configuration. You use
lifecycle.prevent_destroy to enforce this.
Tasks
Task 1: Create the working directory
mkdir -p ~/rb-prevent-destroy-lab
cd ~/rb-prevent-destroy-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" "config" {
filename = "${path.module}/config.yaml"
content = "production configuration\n"
lifecycle {
prevent_destroy = true
}
}
Task 3: Apply the configuration
terraform init
terraform apply
Verify the file:
cat config.yaml
Task 4: Try to remove the resource from the configuration
Edit main.tf to remove the resource:
# Removed the resource block
Task 5: Plan the change
terraform plan
The plan fails with:
Error: Instance cannot be destroyed
Resource local_file.config has lifecycle.prevent_destroy set, but the
planned action is to destroy it.
The plan is rejected. The prevent_destroy has caught the intended destruction.
Task 6: Verify the resource is still in the state
terraform state list
Expected:
local_file.config
The resource is still in the state. The file is still on disk.
Task 7: Restore the configuration
Restore the resource block in the configuration:
resource "local_file" "config" {
filename = "${path.module}/config.yaml"
content = "production configuration\n"
lifecycle {
prevent_destroy = true
}
}
Task 8: Verify the plan is empty
terraform plan
The plan is empty.
Validation
The lab is successful if:
- The configuration was initially applied.
- The plan was rejected when the resource was removed.
- The plan is empty when the resource is restored.
Expected Outcome
At the end of the lab:
+---------------------------------+
| ~/rb-prevent-destroy-lab/ |
| .terraform/ |
| .terraform.lock.hcl |
| config.yaml |
| main.tf |
+---------------------------------+
The config.yaml file is preserved. The plan is empty.
Cleanup
cd ~/rb-prevent-destroy-lab
rm -rf .terraform config.yaml main.tf
The main.tf is the only artefact worth keeping.
What You Learned
You learned the prevent_destroy pattern:
- prevent_destroy is a circuit breaker. It rejects plans that propose to destroy the resource.
- prevent_destroy does not prevent manual destruction. A manual delete via the provider’s console is not prevented.
- prevent_destroy does not prevent replacement. A replacement is destroy + create, which prevent_destroy does not prevent.
- prevent_destroy is a circuit breaker, not a security control. It is for accidental destruction by the configuration.