DEV Community

Cover image for Terraform Lifecycle Meta-Arguments
Sainath Patil
Sainath Patil

Posted on

Terraform Lifecycle Meta-Arguments

As your Terraform setups grow, managing how and when resources should be created, replaced, or protected becomes just as important as defining them.
Terraform’s lifecycle meta-arguments help you control exactly that.

What Are Lifecycle Meta-Arguments?
Lifecycle meta-arguments tell Terraform how it should behave when creating, updating, or destroying a resource.

  • create_before_destroy

  • prevent_destroy

  • ignore_changes

  • replace_triggered_by

  • precondition

  • postcondition


  • create_before_destroy (Zero-Downtime Deployments) By default, Terraform destroys the old resource first and then creates a new one. This can cause downtime for load balancers, Auto Scaling Groups, or any production resource.

create_before_destroy flips the order:

resource "aws_launch_template" "app" {
  name_prefix = "app-template-"

  image_id      = "ami-12345"
  instance_type = "t3.micro"

  lifecycle {
    create_before_destroy = true
  }
}

Enter fullscreen mode Exit fullscreen mode
  • prevent_destroy (Protect Critical Resources) If you want to ensure Terraform NEVER destroys a resource accidentally:
resource "aws_s3_bucket" "logs" {
  bucket = "prod-logs-bucket"

  lifecycle {
    prevent_destroy = true
  }
}

Enter fullscreen mode Exit fullscreen mode
  • ignore_changes (Handle External Modifications) Sometimes AWS updates a field automatically or another external process modifies it. Terraform will detect “drift” and try to revert it even if you don’t want that.
resource "aws_instance" "web" {
  ami           = "ami-12345"
  instance_type = "t3.micro"

  tags = {
    Name = "web-server"
  }

  lifecycle {
    ignore_changes = [
      tags["LastUpdatedBy"],
      user_data,
    ]
  }
}

Enter fullscreen mode Exit fullscreen mode
  • replace_triggered_by (Automatic Resource Replacement) Sometimes you want Terraform to replace a resource only if something else changes.

Example: Replace EC2 instance when Launch Template changes.

resource "aws_instance" "app" {
  ami           = "ami-12345"
  instance_type = "t3.micro"

  lifecycle {
    replace_triggered_by = [
      aws_launch_template.app_latest
    ]
  }
}

Enter fullscreen mode Exit fullscreen mode
  • precondition (Validate Before Deployment) Introduced in Terraform 1.x, precondition helps you fail early if input variables don't meet requirements. Example: Validate that the instance size is not too small.
resource "aws_instance" "db" {
  ami           = "ami-12345"
  instance_type = var.db_size

  lifecycle {
    precondition {
      condition     = contains(["t3.medium", "t3.large"], var.db_size)
      error_message = "Database instance must be at least t3.medium."
    }
  }
}

Enter fullscreen mode Exit fullscreen mode
  • postcondition (Validate After Deployment) This validates the result after creation.

Example: Ensure the S3 bucket actually has versioning enabled:

resource "aws_s3_bucket_versioning" "versioning" {
  bucket = aws_s3_bucket.mybucket.id

  versioning_configuration {
    status = "Enabled"
  }

  lifecycle {
    postcondition {
      condition     = self.versioning_configuration[0].status == "Enabled"
      error_message = "Versioning must remain enabled on the bucket."
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Video: https://youtu.be/60tOSwpvldY?si=UrpTR6YYhV2DiWPG
Conclusion:
Lifecycle meta-arguments give you fine-grained control over how Terraform behaves, reducing downtime, preventing accidents, and ensuring compliance.

Top comments (0)