Cloud  /  Terraform

IaC Terraform 50 guides · updated 2026

Infrastructure as code done right — providers, state, reusable modules, and the workflow patterns that keep multi-cloud deployments sane in 2026.

terraform destroy

terraform destroy removes all infrastructure resources managed by the current Terraform configuration. It’s the reverse of apply — instead of creating or updating, it tears everything down. Used correctly, it’s a powerful tool for cleaning up ephemeral environments. Used carelessly in production, it’s catastrophic.


Basic Usage

Terminal window
terraform destroy

Terraform shows a destruction plan and requires confirmation:

Plan: 0 to add, 0 to change, 5 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes

The destruction order is the reverse of the creation order — Terraform respects dependency relationships and destroys dependents before their dependencies.


Targeted Destruction

Remove a single resource without affecting the rest of the infrastructure:

Terminal window
# Destroy a specific resource
terraform destroy -target=aws_instance.old_server
# Destroy a whole module
terraform destroy -target=module.dev_database
# Destroy multiple specific resources
terraform destroy -target=aws_instance.web -target=aws_eip.web_ip

Key Flags

Terminal window
# Skip confirmation (dangerous — use only in automated teardown scripts)
terraform destroy -auto-approve
# Pass variables
terraform destroy -var="environment=staging"
terraform destroy -var-file="environments/dev.tfvars"
# Preview what would be destroyed without destroying
terraform plan -destroy
# Limit parallelism
terraform destroy -parallelism=5

Protecting Critical Resources from Destruction

Terraform provides lifecycle protections to prevent accidental destruction:

prevent_destroy

resource "aws_db_instance" "production_db" {
identifier = "prod-postgres"
engine = "postgres"
instance_class = "db.r6g.large"
allocated_storage = 100
lifecycle {
prevent_destroy = true # terraform destroy will ERROR — won't proceed
}
}
Error: Instance cannot be destroyed
│ Resource aws_db_instance.production_db has lifecycle.prevent_destroy set,
│ but the plan calls for this resource to be destroyed.

ignore_changes

resource "aws_instance" "app" {
ami = data.aws_ami.latest.id
instance_type = "t3.medium"
lifecycle {
ignore_changes = [ami] # Don't destroy/recreate when AMI is updated externally
}
}

Safe Teardown Workflow for Environments

Terminal window
# 1. Preview what will be destroyed
terraform plan -destroy -out=destroy-plan
# 2. Review — confirm no production resources are in scope
terraform show destroy-plan
# 3. Create a backup if needed (for databases, S3, etc.)
aws rds create-db-snapshot --db-instance-identifier dev-db --db-snapshot-identifier dev-db-final-snapshot
# 4. Apply the destruction
terraform apply destroy-plan

destroy vs. Removing from Config

Two ways to stop managing a resource:

ApproachWhat Happens
terraform destroy -target=resourceDeletes the real resource AND removes from state
Remove resource block from config, then applySame — Terraform sees the resource missing from config and destroys it
terraform state rm resourceRemoves from state only — real resource STAYS, Terraform forgets about it

Use terraform state rm when you want to stop managing a resource without deleting it (hand it off to another team, another state file, or manual management).


destroy in CI/CD: Ephemeral Environments

One of the most powerful uses of destroy is automated teardown of pull request environments:

.github/workflows/teardown-pr-env.yml
on:
pull_request:
types: [closed]
jobs:
destroy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Terraform Init
run: terraform init -input=false
env:
TF_WORKSPACE: pr-${{ github.event.number }}
- name: Terraform Destroy
run: terraform destroy -auto-approve -var="pr_number=${{ github.event.number }}"

This pattern spins up a fresh environment for each PR and tears it down automatically when the PR is closed — keeping costs low and environments clean.


What destroy Does NOT Delete

terraform destroy only removes resources tracked in the current state file. It will NOT delete:


Recovery from Accidental destroy

If you accidentally destroy resources:

  1. If using Terraform Cloud or versioned S3 backend: access the previous state version
  2. Re-run terraform apply — Terraform will recreate all destroyed resources from config
  3. Restore data from backups (Terraform recreates the infrastructure, not the data)

This is why remote state with versioning and prevent_destroy on stateful resources is not optional — it’s essential.