Terraform Lifecycle — Because “Destroy Everything” Isn’t Always the Best Plan
Introduction
Ever applied a Terraform plan and suddenly watched it destroy and recreate a perfectly working resource? 😅
That was me — until I discovered the power of Terraform lifecycle blocks.
If you’ve been working with Terraform for a while, you already know how declarative and powerful it is. But sometimes, Terraform’s default behavior can be… a bit too eager. That’s where lifecycle rules come in — to give you control over how Terraform creates, updates, and destroys your infrastructure resources.
🧠 What Is a Lifecycle Block?
A lifecycle block in Terraform allows you to tweak the default behavior of resource management.
You can think of it as Terraform’s etiquette manual — it helps Terraform know when to act, what to skip, and what not to touch.
Here’s what it looks like:
resource "aws_instance" "web" {
ami = "ami-123456"
instance_type = "t2.micro"
lifecycle {
prevent_destroy = true
create_before_destroy = true
ignore_changes = [tags]
}
}
⚙️ Lifecycle Arguments Explained
1. prevent_destroy
If you’ve ever accidentally destroyed a production resource, this one’s your new best friend.
lifecycle {
prevent_destroy = true
}
Terraform will refuse to destroy this resource — unless you manually remove the flag. It’s your safety net against “oops” moments.
💡 Best used for databases, critical load balancers, and persistent storage.
2. create_before_destroy
This one ensures zero downtime during replacements. Terraform will first create the new resource before destroying the old one.
lifecycle {
create_before_destroy = true
}
It’s extremely useful when dealing with resources like EC2 instances, load balancers, or anything in a production chain that needs to stay online.
🚀 Think of it as blue-green deployment, but for Terraform resources.
3. ignore_changes
Sometimes Terraform shows a diff for changes that don’t matter — like automatically assigned IPs or tags added by cloud providers.
lifecycle {
ignore_changes = [tags, private_ip]
}
Terraform will simply ignore these attributes during plan/apply.
🧩 Perfect when using autoscaling groups, managed services, or provider-added metadata.
💡 Why Use Lifecycle?
Because not all changes should be destructive.
Terraform lifecycle gives you the control to:
✅ Prevent accidental data loss
✅ Maintain zero downtime rollouts
✅ Keep your plans clean from unnecessary updates
✅ Align Terraform with real-world infra patterns
It’s not about changing Terraform’s nature — it’s about teaching it manners. 😄
⚠️ Things to Keep in Mind
prevent_destroycan block legitimate deletions — use it wisely.- Misusing
ignore_changesmay cause drift between your code and real infrastructure. create_before_destroydoesn’t work if the provider doesn’t allow two resources with the same name/ID.
🚀 Conclusion
Terraform lifecycle blocks are one of those underrated features that can save you hours of debugging, unplanned downtime, and heart-stopping “why did this get deleted?” moments.
Once you start using them wisely, your infrastructure becomes more predictable — and Terraform becomes less of a rebel. 😉