DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

LAB: Terraform Lifecycle (FULL HANDS-ON)

βœ… What is lifecycle (quick recap)

lifecycle block controls how Terraform handles resource changes:

lifecycle {
  create_before_destroy = true
  prevent_destroy       = true
  ignore_changes        = [...]
}
Enter fullscreen mode Exit fullscreen mode

πŸš€

🎯 Goal

You will:

  1. Create EC2 instance
  2. Modify it β†’ see replacement behavior
  3. Protect resource from deletion
  4. Ignore specific changes

πŸ“ Project Structure

terraform-lifecycle-lab/
β”œβ”€β”€ main.tf
β”œβ”€β”€ variables.tf
β”œβ”€β”€ terraform.tfvars
β”œβ”€β”€ providers.tf
β”œβ”€β”€ outputs.tf
└── versions.tf
Enter fullscreen mode Exit fullscreen mode

πŸ“„ versions.tf

terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

πŸ“„ providers.tf

provider "aws" {
  region = var.aws_region
}
Enter fullscreen mode Exit fullscreen mode

πŸ“„ variables.tf

variable "aws_region" {
  description = "AWS region"
  type        = string
}

variable "instance_name" {
  description = "EC2 name"
  type        = string
}

variable "instance_type" {
  description = "EC2 type"
  type        = string
}

variable "common_tags" {
  description = "Tags"
  type        = map(string)
}
Enter fullscreen mode Exit fullscreen mode

πŸ“„ terraform.tfvars

aws_region     = "us-east-2"
instance_name  = "lifecycle-lab-instance"
instance_type  = "t2.micro"

common_tags = {
  Project = "LifecycleLab"
  Owner   = "Student"
}
Enter fullscreen mode Exit fullscreen mode

πŸ“„ main.tf (CORE LAB)

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

resource "aws_instance" "example" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = var.instance_type

  tags = merge(var.common_tags, {
    Name = var.instance_name
  })

  lifecycle {

    # βœ… 1. Create new before destroying old
    create_before_destroy = true

    # βœ… 2. Prevent accidental deletion
    prevent_destroy = false

    # βœ… 3. Ignore changes to tags
    ignore_changes = [
      tags
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

πŸ“„ outputs.tf

output "instance_id" {
  value = aws_instance.example.id
}

output "public_ip" {
  value = aws_instance.example.public_ip
}
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ STEP-BY-STEP TESTING


βœ… Step 1 β€” Initialize

terraform init
Enter fullscreen mode Exit fullscreen mode

βœ… Step 2 β€” Create Resource

terraform apply
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ TEST 1 β€” create_before_destroy

Change instance type:

instance_type = "t3.micro"
Enter fullscreen mode Exit fullscreen mode

Run:

terraform apply
Enter fullscreen mode Exit fullscreen mode

βœ… What happens:

  • New EC2 created FIRST
  • Old EC2 destroyed AFTER

πŸ‘‰ Without this β†’ downtime
πŸ‘‰ With this β†’ zero downtime (important for production)


πŸ”₯ TEST 2 β€” prevent_destroy

Change:

prevent_destroy = true
Enter fullscreen mode Exit fullscreen mode

Now run:

terraform destroy
Enter fullscreen mode Exit fullscreen mode

❌ Result:

Terraform will fail:

Error: Instance cannot be destroyed
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ This protects production resources (RDS, S3, etc.)


πŸ”₯ TEST 3 β€” ignore_changes

Step:

  1. Go to AWS Console
  2. Change tag manually (e.g., Name)

Run:

terraform plan
Enter fullscreen mode Exit fullscreen mode

βœ… Result:

No changes detected

πŸ‘‰ Terraform ignores drift for tags


🧠 REAL DEVOPS USAGE

Lifecycle Rule Real Use Case
create_before_destroy Zero downtime deploy (ASG, ALB)
prevent_destroy Protect RDS, S3, DB
ignore_changes External systems modify resource

⚠️ IMPORTANT INTERVIEW POINTS

Q: When should NOT use ignore_changes?
πŸ‘‰ When drift matters (security groups, IAM)

Q: Risk of prevent_destroy?
πŸ‘‰ Blocks CI/CD destroy β†’ must manually disable

Q: Does Terraform automatically use lifecycle?
πŸ‘‰ No β€” must be explicitly defined

Top comments (0)