interview-prep

Crisp answer: The lifecycle block controls how Terraform creates, updates, and destroys a specific resource. The four settings are create_before_destroy, prevent_destroy, ignore_changes, and replace_triggered_by.

create_before_destroy:

resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = "t3.micro"

  lifecycle {
    create_before_destroy = true
  }
}

Default Terraform behaviour on a resource that must be replaced: destroy the old resource first, then create the new one. This causes downtime.

With create_before_destroy = true: create the new resource first, then destroy the old one. Requires that two instances of the resource can exist simultaneously (most can).

Use for: EC2 instances behind an ALB, Launch Templates, ACM certificates.

prevent_destroy:

resource "aws_rds_cluster" "main" {
  cluster_identifier = "prod-db"

  lifecycle {
    prevent_destroy = true
  }
}

Terraform will refuse to destroy this resource even if you run terraform destroy or remove the block from config. Returns an error instead.

Use for: production databases, S3 buckets with irreplaceable data, anything where accidental deletion is catastrophic.

To actually destroy it: remove the prevent_destroy setting first, apply, then destroy.

ignore_changes:

resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = "t3.micro"
  tags          = local.standard_tags

  lifecycle {
    ignore_changes = [
      tags["LastDeployedBy"],   # This tag is set by a deployment tool, not Terraform
      user_data,                # User data changes trigger replace — ignore to prevent
    ]
  }
}

Terraform ignores these attributes when calculating diffs. If the real resource has a different value, no change is planned.

Use for: tags managed by other tools, auto-scaling group sizes managed by AWS, anything that drifts intentionally.

replace_triggered_by:

resource "aws_instance" "web" {
  ami           = var.ami_id

  lifecycle {
    replace_triggered_by = [
      aws_launch_template.web.id,  # Replace instance when the launch template changes
    ]
  }
}

Force a replacement of this resource when another resource changes, even if this resource's own attributes haven't changed.

What to say in the interview:

"The lifecycle block fine-tunes how Terraform handles creates, updates, and destroys. The ones I use most: create_before_destroy for anything behind a load balancer so there's no downtime during replacement, and prevent_destroy on production databases to catch accidental deletes before they happen. ignore_changes is useful when something outside Terraform manages specific attributes — like a deployment tool writing a last-deployed tag. Without ignore_changes, every plan would show that tag as a diff Terraform wants to remove."


My notes