Skip to content

Terraform Level 1, Task 32: Safely Destroying Infrastructure (IAM Role)

Today's task was about the other half of the infrastructure lifecycle: destruction. My objective was to delete an existing IAM Role 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 role 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 Role named iamrole_kirsty. The requirements were: 1. The role iamrole_kirsty was already defined in my main.tf file and (presumably) existed in my AWS account, managed by Terraform. 2. I had to delete this role. 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 IAM Role
resource "aws_iam_role" "role" {
  name = "iamrole_kirsty"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect    = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      }
    ]
  })

  tags = {
    Name        = "iamrole_kirsty"
  }
}
This file correctly defined the iamrole_kirsty 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 role), 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 iamrole_kirsty 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 role again tomorrow, I can just run terraform apply, and Terraform will re-create it exactly as it was defined. - IAM Role: An IAM Role is an identity with permissions that can be assumed by a user or, more commonly, by an AWS service (like an EC2 instance). The role I destroyed was configured to be assumable by the EC2 service, which is a very common pattern.


Deep Dive: A Line-by-Line Explanation of the main.tf File

Understanding the file that defined the resource I was destroying is key.

[Image of an AWS IAM Role icon]

# This is the resource block that defines my IAM Role.
# "aws_iam_role" is the Resource TYPE.
# "role" is the local NAME I use to refer to this role.
resource "aws_iam_role" "role" {

  # The 'name' argument sets the unique name for the role within my AWS account.
  name = "iamrole_kirsty"

  # This is the 'Trust Policy'. It defines *who* is allowed to assume this role.
  # The 'jsonencode' function converts the map into a JSON string.
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect    = "Allow",
        # The 'Principal' is the entity that can assume the role.
        # 'Service = "ec2.amazonaws.com"' means I am trusting the EC2 service.
        # This allows an EC2 instance to assume this role and gain its permissions.
        Principal = {
          Service = "ec2.amazonaws.com"
        },
        # The 'Action' is the specific API call being allowed.
        # 'sts:AssumeRole' is the action of assuming a role.
        Action = "sts:AssumeRole"
      }
    ]
  })

  # Standard tagging to give the role a recognizable name.
  tags = {
    Name = "iamrole_kirsty"
  }
}
When I ran terraform destroy, Terraform read its state file, found the real-world IAM role corresponding to this code, and then made the API call to AWS to delete it.


Common Pitfalls

- Accidentally Deleting Code: A beginner's mistake would be to delete the resource "aws_iam_role" "role" block from the main.tf file and then run terraform apply. While this would also result in the role 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 another resource (like an aws_iam_role_policy_attachment or an aws_iam_instance_profile) was still attached to this role, terraform destroy would fail until those dependent resources were also removed. Terraform is smart enough to manage this order automatically if all resources are in the same configuration.


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