Terraform create_before_destroy Lifecycle Rule Explained

When Terraform needs to replace a resource (destroy and recreate), it follows a specific order. Understanding the create_before_destroy lifecycle rule helps you avoid downtime during infrastructure updates.

Default Behavior: Destroy Then Create

By default, when a resource needs to be replaced, Terraform:

  1. Destroys the old resource.
  2. Creates the new resource.

This causes a window of downtime where neither the old nor new resource exists.

create_before_destroy: Create Then Destroy

With create_before_destroy = true, Terraform reverses the order:

  1. Creates the new resource first.
  2. Waits for it to be fully operational.
  3. Destroys the old resource.
resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = "t3.micro"

  lifecycle {
    create_before_destroy = true
  }
}

Real-World Example: Auto Scaling Launch Template

resource "aws_launch_template" "app" {
  name_prefix   = "app-"
  image_id      = var.ami_id
  instance_type = "t3.micro"

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_autoscaling_group" "app" {
  launch_template {
    id      = aws_launch_template.app.id
    version = "$Latest"
  }
  min_size         = 2
  max_size         = 5
  desired_capacity = 2
}

When the AMI is updated, a new launch template is created before the old one is removed, ensuring the ASG always has a valid template.

Example: TLS Certificate Rotation

resource "aws_acm_certificate" "cert" {
  domain_name       = "example.com"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

The new certificate is issued and validated before the old one is deleted, preventing HTTPS downtime.

Other Useful Lifecycle Rules

lifecycle {
  create_before_destroy = true   # Create new before destroying old
  prevent_destroy       = true   # Block any destroy operation (great for databases)
  ignore_changes        = [tags] # Ignore drift in specific attributes
}

Key Takeaway

Always use create_before_destroy = true for production resources where availability matters — load balancers, certificates, launch templates, and DNS records. Pair it with prevent_destroy = true on critical resources like databases to add an extra safety net.

(Visited 1 times, 1 visits today)