Step 01 of 06
Learn the concept
The most expensive learning resource is the one you forgot. A tiny instance is annoying; a NAT Gateway, load balancer, retained disk or managed control plane can bill quietly for weeks. Teardown is not cleanup after the lesson. It is part of the lesson.
The ideas this is made of
Destroy is an apply in reverse
terraform destroy builds a plan whose goal is absence for every resource in state. It still depends on state being correct, providers being reachable and dependencies being ordered. Read it. A destroy plan can reveal that something important is in the same state file as the learning environment. If the plan looks surprising, stop and inspect before confirming.
Lifecycle rules can save or trap you
prevent_destroy = true blocks accidental deletion of critical resources. It also blocks intentional teardown until removed or bypassed by design. create_before_destroy can reduce downtime during replacement but may double cost during overlap. Lifecycle rules are sharp tools. Use them when the risk is named, not as decorative safety theatre.
Some resources outlive their parent
Cloud platforms often retain disks, snapshots, elastic IPs, load balancers or DNS records depending on settings and ownership. Kubernetes services of type LoadBalancer can create cloud load balancers outside the Terraform resource you are staring at. A clean Terraform destroy is necessary, not sufficient. The provider console and billing tags get the final word.
Tags are cost instrumentation
A tag such as Project=beacon and ManagedBy=terraform is not decoration. It lets cost tools group charges and lets humans search for leftovers. Add Owner and Expires tags in real accounts. If a resource cannot be attributed, it cannot be confidently deleted, and that is how idle infrastructure becomes a permanent line item.
Budgets turn mistakes into small mistakes
A budget alert will not stop every charge, but it changes discovery time from end-of-month to same-day. Set a low threshold in a learning account, such as $5, and send it somewhere you read. The alert is not a substitute for destroy. It is the smoke alarm next to the stove you still need to turn off.
resource "aws_db_instance" "critical" {
identifier = "example-critical-db"
lifecycle {
prevent_destroy = true
}
}
This protects a database from accidental deletion, but it also makes teardown fail until the operator handles the protection deliberately. It belongs with a runbook, not as a surprise in a module.
What can remain after destroy
| Survivor | Why it remains | Where to check |
|---|---|---|
Disk or volume | Retain setting | EC2 volumes |
Elastic IP | Detached address | VPC addresses |
Snapshot | Backup policy | Snapshots |
Load balancer | K8s service | EC2 or ELB |
DNS record | Separate zone | Route 53 |
What these are called on the job
Destroy plan — A Terraform plan whose proposed actions remove resources from the provider and state.
Lifecycle block — Terraform resource settings that change replacement and deletion behavior.
Deletion protection — A provider-side guard that blocks deletion until disabled.
Cost allocation tag — A tag used by billing tools to group and attribute charges.
