DevOpsLesson
DevOpsLesson

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Stay Updated

Get notified about new tutorials and features.

Tutorials

  • What is DevOps?
  • Docker Tutorial
  • Terraform Tutorial
  • CI/CD Pipeline
  • All Tutorials

Roadmaps

  • DevOps Engineer
  • Cloud Engineer
  • SRE Path
  • All Roadmaps

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 DevOpsLesson. All rights reserved.

DOCKERKUBERNETESTERRAFORMAWSCI/CDLINUXGITDEVOPS ROADMAPCLOUD ROADMAPSRE ROADMAPGIT CHEATSHEETDOCKER CHEATSHEETK8S CHEATSHEETTF CHEATSHEETLINUX CHEATSHEETDOCKERFILE LINTERYAML VALIDATORCRON PARSERREGEX TESTER

Terraform Tutorial

Introduction to Terraform
Installing Terraform
The Terraform Core Workflow
Terraform Variables and Outputs
Terraform State and Backends
Terraform Modules
Terraform Data Sources
Terraform Count and for_each
Terraform Expressions and Functions
Terraform Dynamic Blocks
Terraform Workspaces
Terraform with AWS
Terraform Provisioners
Terraform CI/CD Pipeline
Terraform Security

terraform destroy

PreviousPrev
Next

Learn terraform destroy, safely tearing down infrastructure, using -target for partial destroys, understanding the destroy plan, and when to use destroy vs decommission. Includes terraform fmt and validate.

What Is terraform destroy?

terraform destroy removes all infrastructure resources managed by your Terraform configuration. It is the opposite of terraform apply.

terraform destroy

Terraform reads your configuration and state file, calculates a destroy plan (everything that exists gets removed), shows you the plan, and waits for approval before deleting anything.

Warning: terraform destroy is permanent. Deleted cloud resources cannot be recovered unless you have backups (e.g., RDS snapshots, EBS snapshots). Always review the destroy plan carefully.

The Destroy Plan

Before destroying anything, Terraform shows you exactly what will be deleted:

Terraform will destroy all your managed infrastructure, as shown below.
These resources will be destroyed in the proper reverse order.

  # aws_instance.web will be destroyed
  - resource "aws_instance" "web" {
      - ami           = "ami-0c55b159cbfafe1f0" -> null
      - instance_type = "t3.micro" -> null
      - id            = "i-0abc12345def67890" -> null
      - public_ip     = "54.123.45.67" -> null
    }

  # aws_security_group.web will be destroyed
  - resource "aws_security_group" "web" { ... }

  # aws_subnet.public will be destroyed
  - resource "aws_subnet" "public" { ... }

  # aws_vpc.main will be destroyed
  - resource "aws_vpc" "main" { ... }

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

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

Notice the reverse dependency order: Terraform destroys in the reverse of the creation order. The EC2 instance is destroyed before the security group, which is destroyed before the subnet, which is destroyed before the VPC. This prevents dependency errors (e.g., you cannot delete a VPC that still has running instances).

When to Use terraform destroy

Use CaseAppropriate?
Tearing down a dev/test environment✅ Perfect use case
Cleaning up after a tutorial or experiment✅ Perfect use case
Removing a feature branch environment✅ Standard practice
Decommissioning part of production⚠️ Use with extreme caution + backup strategy
"I'll just recreate it" in production❌ Almost always wrong

terraform destroy is most commonly used for ephemeral environments, dev environments, feature branch previews, CI/CD testing environments, and tutorial cleanup.

Partial Destroy with -target

To destroy a single resource (or module) without touching the rest:

# Destroy a single resource
terraform destroy -target=aws_instance.web

# Destroy an entire module
terraform destroy -target=module.database

Terraform will show a destroy plan for only the targeted resource:

  # aws_instance.web will be destroyed
  - resource "aws_instance" "web" {
      - id = "i-0abc12345def67890" -> null
    }

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

Caution: -target can leave your state inconsistent. If other resources depended on the destroyed resource, they still exist in state but their dependency is gone. Always run a full plan after a targeted destroy to check for consistency.

Auto-Approve in CI/CD

Like apply, you can skip the confirmation with -auto-approve:

terraform destroy -auto-approve

This is commonly used in CI/CD pipelines to automatically tear down ephemeral environments:

# GitLab CI, destroy on branch delete
teardown:
  stage: destroy
  script:
    - terraform init -input=false
    - terraform destroy -input=false -auto-approve
  when: manual

Preview the Destroy Plan Without Destroying

To see the destroy plan without any risk, use terraform plan -destroy:

terraform plan -destroy

This is functionally equivalent to terraform destroy without the actual deletion, great for reviewing what would be destroyed before committing.

The destroy Lifecycle Hook

If you want certain resources to be retained even when the configuration is removed, use the prevent_destroy lifecycle argument:

resource "aws_s3_bucket" "critical_data" {
  bucket = "my-production-data"

  lifecycle {
    prevent_destroy = true
  }
}

If you try to destroy this resource (or remove it from your config), Terraform will error:

╷
│ Error: Instance cannot be destroyed
│ Resource aws_s3_bucket.critical_data has lifecycle.prevent_destroy set to true.
│ To allow this object to be destroyed, remove the lifecycle block or set
│ prevent_destroy = false.
╵

Use prevent_destroy for critical resources like production databases, S3 buckets with important data, or any resource where accidental deletion would be catastrophic.


terraform fmt, Format Your Code

While you have your terminal open, terraform fmt is a command you will use constantly:

terraform fmt

It automatically formats all .tf files in the current directory to match the Terraform style guide, consistent indentation, aligned = signs, and proper spacing.

# Format and show which files were changed
terraform fmt -diff

# Format all files recursively (including modules)
terraform fmt -recursive

# Check formatting without making changes (useful in CI)
terraform fmt -check

Example, before formatting:

resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
  tags = {
    Name = "web-server"
  }
}

After terraform fmt:

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  tags = {
    Name = "web-server"
  }
}

Pro tip: Add terraform fmt -check to your CI pipeline. If anyone submits unformatted code, the pipeline fails, this enforces consistent style across the team without manual code review comments.


terraform validate, Validate Your Configuration

terraform validate checks your configuration for syntax errors and internal consistency:

terraform validate

Successful output:

Success! The configuration is valid.

Error example:

╷
│ Error: Unsupported argument
│   on main.tf line 8
│ An argument named "instanse_type" is not expected here.
│ Did you mean "instance_type"?
╵

validate catches:

  • Syntax errors (missing braces, typos)
  • References to undeclared variables or resources
  • Invalid attribute names for a resource type
  • Type mismatches (e.g., passing a string where a number is expected)

What validate does NOT check:

  • Whether the cloud credentials are valid
  • Whether the AMI ID exists in your region
  • Whether the VPC ID actually exists
  • Anything that requires calling cloud APIs
# Typical workflow before pushing code:
terraform fmt -recursive
terraform validate
terraform plan

Knowledge Check

Exercise

Question 1: Destroy Order

You have a VPC, a subnet inside the VPC, and an EC2 instance inside the subnet. When you run terraform destroy, in what order does Terraform destroy these resources?

Exercise

Question 2: prevent_destroy

A developer accidentally removes the aws_rds_cluster.production resource block from the Terraform config. What happens when they run terraform apply?

Exercise

Question 3: terraform fmt

Your CI/CD pipeline includes terraform fmt -check. A developer submits a merge request with an unformatted .tf file. What happens?

PreviousPrev
Next

Continue Learning

terraform init

Learn exactly what terraform init does, downloading providers, setting up backends, creating the lock file, and how to use init flags like -upgrade and -reconfigure.

10 min read·Easy

terraform plan

Master terraform plan, understand execution plan output symbols (+/-/~/+/-), save plan files, target specific resources, detect configuration drift, and use plan in CI/CD pipelines.

12 min read·Easy

terraform apply

Learn terraform apply in depth, reviewing and confirming the plan, auto-approve for CI/CD, applying saved plan files, parallel execution, watching real-time output, and handling apply errors safely.

12 min read·Easy

Explore Related Topics

AW

AWS Tutorials

Provision AWS infrastructure with Terraform

CI

CI/CD Tutorials

Run terraform plan/apply in CI pipelines

Try the Tool

YAML Validator

Validate Terraform and Kubernetes YAML configs before applying.

On This Page

What Is terraform destroy?The Destroy PlanWhen to Use terraform destroyPartial Destroy with -targetAuto-Approve in CI/CDPreview the Destroy Plan Without DestroyingThe destroy Lifecycle Hookterraform fmt, Format Your Codeterraform validate, Validate Your ConfigurationKnowledge Check