In this article, we will take a look at the various stages a Terraform resource goes through during its lifetime. We will look at the default resource behavior before looking at the lifecycle meta-argument, which can allow you to customize that behavior.
A resource
block defines a piece of infrastructure with the given settings. When the resource
block is defined in code, the resource object does not actually exist until terraform apply
is executed. Applying a configuration can result in the creation, modification, or destruction of a resource, depending on the configuration and state of the infrastructure. Terraform will make the real infrastructure match the configured settings for the resource.
Once an object is created, it is saved in the Terraform state. Terraform can then update the object if its settings are changed in the configuration or destroy it if the resource
is removed from the configuration.
Depending on the settings defined in the configuration, Terraform will take one of the following actions when applying the configuration:
- Create — creates the object with the defined settings.
- Destroy — destroys the object when the configuration no longer exists.
- Update-in-place — updates the object accordingly when the settings in the
resource
block are changed. For example, adding a disk to a VM in Azure can be created and added without destroying the VM first. - Destroy and recreate — destroys the object before re-creating it, if certain setting changes within the
resource
configuration block means, this must happen on the given platform. For example, changing the name of a VM in Azure is not possible without first destroying the VM. It is destroyed and then recreated with the new VM name specified in the settings of theresource
block.
Terraform state can contain very sensitive data. Sometimes this is unavoidable because of the design of certain Terraform providers or because the definition of what is sensitive isn’t always simple and may vary between individuals and organizations. Spacelift provides two different approaches for sanitizing values when resources are stored or passed to Plan policies:
- Default Sanitization: All string values are sanitized.
- Smart Sanitization: Only the values marked as sensitive are sanitized.
Learn more about how Spacelift can help you with Resource Sanitization, and get started on your journey by creating a free trial account.
Controlling the flow of Terraform operations is possible using the lifecycle
meta-argument. This is useful in scenarios when you need to protect items from getting changed or destroyed.
A common scenario that requires the use of a lifecycle
meta-argument occurs when the Terraform provider itself does not handle a change correctly and so can be safely ignored, rather than the provider attempting to update an object necessarily. With the provider version updates, these “bugs” are slowly ironed out, at which point the lifecycle
meta-argument can be removed from the resource.
The lifecycle
meta-argument can be used within any resource
block like so:
resource "azurerm_resource_group" "example-rg" {
resource settings...
lifecycle {
ignore_changes = true
}
}
There are several attributes available for use with the lifecycle
meta-argument:
- create_before_destroy
When Terraform determines it needs to destroy an object and recreate it, the normal behavior will create the new object after the existing one is destroyed. Using this attribute will create the new object first and then destroy the old one. This can help reduce downtime. Some objects have restrictions that the use of this setting may cause issues with, preventing objects from existing concurrently. Hence, it is important to understand any resource constraints before using this option.
lifecycle {
create_before_destroy = true
}
- prevent_destroy
This lifecycle option prevents Terraform from accidentally removing critical resources. This is useful to avoid downtime when a change would result in the destruction and recreation of resource
. This block should be used only when necessary as it will make certain configuration changes impossible.
lifecycle {
prevent_destroy = true
}
Terraform will error when it attempts to destroy a resource when this is set to true:
Error: Instance cannot be destroyed
resource details...
Resource [resource_name] has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.
- ignore_changes
This lifecycle option can be useful when attributes of a resource are updated outside of Terraform, for example, when an Azure Policy automatically applies tags. When Terraform detects the changes the Azure Policy has applied, it will ignore them and not attempt to modify the tag. Attributes of the resource that need to be ignored can be specified. In the example below, the department tag will be ignored:
lifecycle {
ignore_changes = [
tags["department"]
]
}
If all attributes are to be ignored, then the all
keyword can be used. This means that Terraform will never update the object but will be able to create or destroy it.
lifecycle {
ignore_changes = [
all
]
}
- replace_triggered_by
Lastly, this option forces the replacement of the resource when the specified resource is changed. This may be useful when the resource references another resource and needs to be replaced when this happens, for example, when a resource id changes. In the example below, when the id of VM 1 changes, the resource will also be replaced. For this option to take effect, references to the target resource must be under Terraform management (in the state file).
Understanding the default behavior of the Terraform resource lifecycle can help avoid unwanted downtime when Terraform executes operations. The lifecycle of every resource can be manipulated as needed using the lifecycle meta-argument.
Cheers!
Manage Terraform Better and Faster
If you are struggling with Terraform automation and management, check out Spacelift. It helps you manage Terraform state, build more complex workflows, and adds several must-have capabilities for end-to-end infrastructure management.
Terraform Essential Components Cheatsheet
Whenever you're embarking on a new journey or seeking to refine your foundational knowledge.