Going to AWS re:Invent 2024?

➡️ Book a meeting with Spacelift

Terraform

Terraform Resource Lifecycle Meta-Argument [Examples]

The Lifecycle of a Terraform Resource

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.

What is a Terraform Resource?

A Terraform 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.

Terraform Resource Lifecycle

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.

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 the resource 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:

Learn more about how Spacelift can help you with Resource Sanitization, and get started on your journey by creating a free trial account.

What is Terraform Lifecycle Meta-Argument?

The Terraform lifecycle is a nested configuration block within a resource block.  The lifecycle meta-argument can be used to specify how Terraform should handle the creation, modification, and destruction of resources. Meta-arguments are arguments used in resource blocks.

Terraform Lifecycle Meta-Argument Example

he lifecycle meta-argument can be used within any resource block like so:

resource "azurerm_resource_group" "example-rg" {
resource settings...
  lifecycle {
     ignore_changes = true
  }
}

Managing the Resource Lifecycle Using the Lifecycle Meta-Argument

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.

create_before_destroy

lifecycle {
  create_before_destroy = true
}

prevent_destroy

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

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

precondition and postcondition

You can also use custom condition checks with the lifecycle meta-argument. By adding precondition and postcondition blocks with a lifecycle block, you can specify assumptions and guarantees about how resources and data sources operate.

The precondition block is used to ensure a certain condition is met before the resource is created, and the postcondition block is used to execute specific actions or checks after the resource is created.

The example below has a precondition set for the creation of an AWS instance that throws an error id the architecture is not equal to “x86_64”.

resource "aws_instance" "example" {
 instance_type = "t2.micro"
 ami           = "ami-abc123"

 lifecycle {
   # The AMI ID must refer to an AMI that contains an operating system
   # for the `x86_64` architecture.
   precondition {
     condition     = data.aws_ami.example.architecture == "x86_64"
     error_message = "The selected AMI must be for the x86_64 architecture."
   }
 }
}

Key Points

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.

Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.

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.

Start free trial

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide