Terraform Tutorial — Resource Lifecycle
The lifecycle block gives you fine-grained control over how Terraform creates, updates, and destroys resources. These settings are essential for production infrastructure where you need to avoid downtime or prevent accidental deletion.
create_before_destroy
By default, Terraform destroys the old resource, then creates the new one. This causes downtime. create_before_destroy reverses the order:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
lifecycle {
create_before_destroy = true
}
}
When to use: Resources that can’t have downtime — instances behind a load balancer, databases, etc.
prevent_destroy
Blocks Terraform from destroying a resource, even during terraform destroy:
resource "aws_s3_bucket" "critical_data" {
bucket = "company-critical-data"
lifecycle {
prevent_destroy = true
}
}
If someone tries to destroy this resource:
Error: Instance cannot be destroyed
Resource aws_s3_bucket.critical_data has lifecycle.prevent_destroy set,
but the plan calls for this resource to be destroyed.
When to use: Databases, S3 buckets with important data, production infrastructure you never want accidentally deleted.
💡 Tip:
prevent_destroyprotects againstterraform destroyand plan changes that would replace a resource. To remove the resource from Terraform’s management, first removeprevent_destroy, then remove the resource block.
ignore_changes
Tells Terraform to ignore changes to specific attributes. Useful when something outside Terraform modifies a resource:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
lifecycle {
ignore_changes = [ami, tags]
}
}
Now if someone updates the AMI or tags through the AWS console, Terraform won’t try to revert those changes.
Ignore All Changes
lifecycle {
ignore_changes = all
}
This makes Terraform manage the resource’s creation and deletion but ignore all attribute changes. Useful for resources managed primarily outside Terraform.
replace_triggered_by
Force a resource to be replaced when another resource or value changes:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
lifecycle {
replace_triggered_by = [
aws_security_group.web.id
]
}
}
If the security group is replaced, the instance is also replaced.
Lifecycle Summary
| Setting | Effect |
|---|---|
create_before_destroy |
New resource created before old one is destroyed |
prevent_destroy |
Blocks any plan that would destroy the resource |
ignore_changes |
Ignores changes to specific attributes |
replace_triggered_by |
Forces replacement when referenced resources change |
What’s Next?
You understand lifecycle management. Next, let’s get an overview of all the meta-arguments available on resources — count, for_each, depends_on, provider, and lifecycle.