Terraform Level 1, Task 33: Safely Destroying Infrastructure (AWS VPC)¶
Today's task was about the other half of the infrastructure lifecycle: destruction. My objective was to delete an existing AWS VPC that was no longer needed, using Terraform. The key requirement was to do this without deleting the main.tf file that contained the provisioning code. This would allow the team to re-create the VPC again later just by running terraform apply.
This was a fantastic lesson in how Terraform manages the full lifecycle of a resource. I learned how to use the terraform destroy command to tear down infrastructure safely. This document is my detailed, first-person guide to that entire process, explaining the concepts and the core Terraform commands in depth.
Table of Contents¶
The Task¶
My objective was to use Terraform to delete an existing AWS VPC named xfusion-vpc. The requirements were:
1. The VPC xfusion-vpc was already defined in my main.tf file and (presumably) existed in my AWS account, managed by Terraform.
2. I had to delete this VPC.
3. I had to keep the provisioning code in main.tf for future use.
My Step-by-Step Solution¶
The process was very straightforward. Since the code in main.tf accurately described the infrastructure I wanted to delete, I just needed to use the terraform destroy command.
Phase 1: Reviewing the Code¶
In the /home/bob/terraform directory, I first inspected my main.tf file to confirm what I was about to destroy.
# Provision VPC
resource "aws_vpc" "this" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "xfusion-vpc"
}
}
xfusion-vpc that I needed to delete.
Phase 2: The Terraform Workflow¶
From my terminal in the same directory, I executed the following commands.
- Initialize:
terraform init. This is always a good first step to ensure the providers are loaded and the backend is ready. - Destroy: This is the main command for the task.
Terraform read my
terraform destroymain.tffile and myterraform.tfstatefile (which had a record of the existing VPC), and generated a plan to destroy all the resources it was managing. It presented me with a summary ofPlan: 0 to add, 0 to change, 1 to destroy. - Confirm: Terraform then asked for confirmation. This is a critical safety step to prevent accidental deletion.
Do you really want to destroy all resources? ... Only 'yes' will be accepted to approve.I typedyesand pressed Enter. - Terraform then proceeded to delete the
xfusion-vpcfrom AWS. The success messageDestroy complete! Resources: 1 destroyed.was my confirmation that the task was done.
Why Did I Do This? (The "What & Why")¶
- Infrastructure Lifecycle Management: This task was the perfect demonstration that Infrastructure as Code isn't just about creating resources; it's about managing their full lifecycle. This includes creation, updates (like the task where I changed an instance type), and, just as importantly, deletion.
- terraform destroy: This is the clean, safe, and standard way to tear down infrastructure managed by Terraform. It reads your configuration and state file to create a complete plan of everything that will be deleted, and it's smart enough to delete resources in the correct order to avoid dependency errors.
- Keeping the Code: The key requirement was to "keep the provisioning code." This is the beauty of IaC. By running terraform destroy, I am not deleting my main.tf file. My code, the blueprint for my infrastructure, is perfectly safe in my Git repository. I have only destroyed the live, existing resource in the cloud. If I need the VPC again tomorrow, I can just run terraform apply, and Terraform will re-create it exactly as it was defined.
Deep Dive: The Core Terraform Workflow Commands Explained¶
This task was a great time to review the entire Terraform workflow and what's happening under the hood for each command.
[Image of the Terraform init, plan, apply/destroy workflow]
-
terraform init(Initialize)- What it does: This is the first command to run in any new or checked-out Terraform directory. It looks at your
providerblocks (likeprovider "aws"). - How it works: It reaches out to the internet (or a local cache) and downloads the necessary provider plugins (e.g., the
awsprovider executable). - Files Created/Modified:
.terraform/directory: This new directory is where Terraform stores the downloaded provider plugins..terraform.lock.hcl: This file is a "lock file" that records the exact versions of the providers that were downloaded. This is critical for teamwork, as it ensures that every person on your team uses the exact same provider versions, preventing "it works on my machine" problems. You should commit this file to Git.
- What it does: This is the first command to run in any new or checked-out Terraform directory. It looks at your
-
terraform plan(Plan)- What it does: This is a non-destructive "dry run." It's Terraform's safety mechanism.
- How it works: It performs a three-way comparison:
- Desired State: Your current code in the
.tffiles. - Recorded State: The
terraform.tfstatefile, which is a JSON file that records what Terraform thinks it has already built. - Actual State: It makes read-only API calls to the cloud provider (e.g., AWS) to check what actually exists.
- Desired State: Your current code in the
- Output: It shows you a summary of what actions it will take:
+(create),~(change in-place),-(destroy), or-/+(destroy and re-create). - Files Created/Modified: None. It's a read-only operation.
-
terraform apply(Apply)- What it does: This is the command that makes changes. It executes the plan to make your cloud infrastructure match your code.
- How it works: It first runs a
planand shows you the summary. It then requires you to typeyesto approve the changes. Once you approve, it begins making the API calls to your cloud provider. - Files Created/Modified:
terraform.tfstate: This is the most important file. After theapplyis successful, Terraform updates the state file to record the new reality. For myaws_vpc, it would add the VPC's unique ID to this file.terraform.tfstate.backup: A backup of the previous state file, kept as a safety measure.
-
terraform destroy(Destroy)- What it does: This is the command to delete the infrastructure managed by your code.
- How it works: It reads your code and your
terraform.tfstatefile to see what resources currently exist. It then generates a plan to destroy all of them, showing you a summary (e.g.,Plan: 0 to add, 0 to change, 1 to destroy.). It also requires ayesto approve. - Files Created/Modified:
terraform.tfstate: After thedestroyis successful, Terraform updates the state file to be empty, recording that the resources no longer exist.
Common Pitfalls¶
- Accidentally Deleting Code: A beginner's mistake would be to delete the resource "aws_vpc" "this" block from the main.tf file and then run terraform apply. While this would also result in the VPC being deleted (Terraform would see it's in the state but not in the code), it violates the task's requirement to "keep the provisioning code" for later use.
- Ignoring the Confirmation: The terraform destroy command always asks for a yes confirmation. It's critical to read the plan carefully before typing yes to ensure you are not about to accidentally delete your entire production environment.
- Dependencies: If any other resources (like subnets, security groups, or EC2 instances) were still running inside this VPC and were managed by the same Terraform state, terraform destroy would be smart enough to delete them in the correct order. If they were not managed by Terraform (i.e., created manually), the VPC deletion would fail with a "DependencyViolation" error, and I would have to delete those resources manually first.
Exploring the Essential Terraform Commands¶
- terraform init: Prepared my working directory and downloaded the AWS provider.
- terraform destroy: The main command for this task. It reads the state file and the configuration to create a plan to delete all managed resources. It is the opposite of apply.
- terraform plan: Shows a "dry run" of the changes apply would make.
- terraform apply: Executes the plan to create or update resources.
- terraform plan -destroy: A non-interactive way to see what terraform destroy would do without actually running it. This is a great safety check.
- terraform destroy -target=[resource_address]: A more advanced command to destroy a single, specific resource (e.g., terraform destroy -target=aws_vpc.this) without touching any other resources defined in the configuration.