Skip to content

Terraform Level 1, Task 31: Safely Destroying Infrastructure

Today's task was about the other half of the infrastructure lifecycle: destruction. My objective was to delete an existing IAM Group 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, allowing the team to re-create the group again later just by re-running the "apply" command.

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 IAM Group named iamgroup_kareem. The requirements were: 1. The group iamgroup_kareem was already defined in my main.tf file and (presumably) existed in my AWS account, managed by Terraform. 2. I had to delete this group. 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.

# This resource was already in main.tf
resource "aws_iam_group" "this" {
  name = "iamgroup_kareem"
}
This file correctly defined the iamgroup_kareem that I needed to delete.

Phase 2: The Terraform Workflow

From my terminal in the same directory, I executed the following commands.

  1. Initialize: terraform init. This is always a good first step to ensure the providers are loaded and the backend is ready.
  2. Destroy: This is the main command for the task.
    terraform destroy
    
    Terraform read my main.tf file and my terraform.tfstate file (which had a record of the existing group), and generated a plan to destroy all the resources it was managing. It presented me with a summary of Plan: 0 to add, 0 to change, 1 to destroy.
  3. 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 typed yes and pressed Enter.
  4. Terraform then proceeded to delete the iamgroup_kareem from AWS. The success message Destroy 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 group 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]

  1. 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 provider blocks (like provider "aws").
    • How it works: It reaches out to the internet (or a local cache) and downloads the necessary provider plugins (e.g., the aws provider 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.
  2. 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:
      1. Desired State: Your current code in the .tf files.
      2. Recorded State: The terraform.tfstate file, which is a JSON file that records what Terraform thinks it has already built.
      3. Actual State: It makes read-only API calls to the cloud provider (e.g., AWS) to check what actually exists.
    • 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.
  3. 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 plan and shows you the summary. It then requires you to type yes to 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 the apply is successful, Terraform updates the state file to record the new reality. For my aws_iam_group, it would add the group's unique ARN and ID to this file.
      • terraform.tfstate.backup: A backup of the previous state file, kept as a safety measure.
  4. 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.tfstate file 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 a yes to approve.
    • Files Created/Modified:
      • terraform.tfstate: After the destroy is 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_iam_group" "this" block from the main.tf file and then run terraform apply. While this would also result in the group 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. - Destroying a Single Resource: If my main.tf file contained multiple resources (e.g., a user, a group, and a policy) but I only wanted to destroy the group, the correct command would have been terraform destroy -target=aws_iam_group.this. Running a plain terraform destroy would have deleted everything.


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_iam_group.this) without touching any other resources defined in the configuration.