By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(For Engineers Who Need to Ship, Not Just Study)
Terraform’s lifecycle meta-arguments are like the traffic rules for your infrastructure: they tell Terraform how to modify or replace resources without causing accidents. Ignore them, and you’ll either: - Break production (e.g., deleting a database before its replacement is ready).- Waste money (e.g., recreating resources unnecessarily).- Lose data (e.g., accidentally nuking a stateful resource like an EBS volume).
Real-world scenario:You’re deploying a new version of an EC2 instance with updated user data. Without create_before_destroy, Terraform will: 1. Destroy the old instance (downtime!).2. Create the new one (hope it boots fast!).With create_before_destroy, Terraform flips the order: 1. Create the new instance (still running the old one).2. Destroy the old one (zero downtime).
create_before_destroy
This is non-negotiable for production workloads. If you’re not using lifecycle rules, you’re playing Russian roulette with your infrastructure.
prevent_destroy
terraform destroy
ignore_changes
last_modified
desired_count
replace_triggered_by
taint
>= 1.0.0
aws configure
Deploy an EC2 instance with create_before_destroy to ensure zero downtime during updates.
Create main.tf:
main.tf
provider "aws" { region = "us-east-1" } resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 instance_type = "t3.micro" user_data = file("user_data.sh") # Your startup script # Lifecycle rule: Create new instance before destroying old one lifecycle { create_before_destroy = true } tags = { Name = "web-server" } }
Create user_data.sh:
user_data.sh
#!/bin/bash echo "Hello, World!" > /var/www/html/index.html
terraform init terraform apply -auto-approve
Verify:- Go to the AWS EC2 console.- Check the instance is running (web-server).
web-server
Modify user_data.sh to:
#!/bin/bash echo "Hello, NEW World!" > /var/www/html/index.html
Now update the Terraform config to force a replacement (e.g., change the AMI):
resource "aws_instance" "web" { ami = "ami-0abcdef1234567890" # New AMI ID instance_type = "t3.micro" user_data = file("user_data.sh") lifecycle { create_before_destroy = true } }
Apply the changes:
terraform apply -auto-approve
What happens?1. Terraform creates a new instance with the new AMI.2. Once the new instance is healthy, Terraform destroys the old one.3. No downtime!
Verify:- SSH into the new instance: bash ssh -i your-key.pem ec2-user@<NEW_INSTANCE_IP> cat /var/www/html/index.html # Should show "Hello, NEW World!"
bash ssh -i your-key.pem ec2-user@<NEW_INSTANCE_IP> cat /var/www/html/index.html # Should show "Hello, NEW World!"
hcl resource "aws_s3_bucket" "backups" { bucket = "my-critical-backups" lifecycle { prevent_destroy = true } }
hcl resource "aws_autoscaling_group" "app" { desired_capacity = 2 lifecycle { ignore_changes = [desired_capacity] } }
hcl tags = { Environment = "prod" Terraform = "true" }
hcl resource "aws_instance" "app" { ami = var.ami_id lifecycle { replace_triggered_by = [var.ami_id] } }
destroy
Delete*
desired_capacity
ignore_changes = [desired_capacity]
security_groups
❌ prevent_destroy (wrong, this blocks deletion entirely)
"How do you prevent Terraform from deleting a production database?"
prevent_destroy = true
❌ ignore_changes (wrong, this only ignores updates)
"What happens if you don’t use create_before_destroy on an EC2 instance?"
Challenge:You have an S3 bucket (my-app-logs) that AWS Lambda writes logs to. The bucket’s last_modified timestamp changes every time Lambda writes a log, causing Terraform to try to "fix" it. How do you stop Terraform from touching the bucket?
my-app-logs
Solution:
resource "aws_s3_bucket" "logs" { bucket = "my-app-logs" lifecycle { ignore_changes = [tags, last_modified] # Ignore timestamp changes } }
Why it works:Terraform will now ignore changes to last_modified, preventing unnecessary updates.
lifecycle { create_before_destroy = true }
lifecycle { prevent_destroy = true }
lifecycle { ignore_changes = [tags] }
lifecycle { replace_triggered_by = [var.ami_id] }
⚠️ Exam Traps:- prevent_destroy does not prevent terraform destroy from running—it just errors out.- ignore_changes does not prevent Terraform from creating the resource—it only ignores updates.- create_before_destroy requires the resource to support parallel existence (e.g., EC2, Lambda, but not EBS volumes).
Lifecycle meta-arguments are your safety net in Terraform. Use them like you’d use a seatbelt: always, unless you have a very good reason not to. Now go deploy something—safely. ?
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.