Introduction
Terraform is a powerful tool for describing infrastructure as code (IaC), enabling developers and administrators to define and manage infrastructure resources in a declarative manner. One of the key aspects of effective work with Terraform is understanding the concepts related to the lifecycle of resources and metaarguments. These elements are crucial for precise resource management in the cloud and ensuring that our infrastructure is always in line with the intended state.
In this article, we will take a closer look at lifecycle metaarguments, specifically the create_before_destroy
argument. This will help us better understand how to control the update process of certain problematic resources. It’s worth exploring these advanced techniques to efficiently manage infrastructure and achieve a high level of reliability and scalability using Terraform as a tool in your workflow.
Lifecycle meta-arguments
Lifecycle metaarguments in Terraform are special attributes that you can assign to resources in infrastructure definitions. They are used to control the lifecycle of these resources, determining when and how Terraform should manage them during operations such as creation, updating, or deletion.
One of the Lifecycle metaarguments is the “create_before_destroy” which is often used when dealing with resources that require transitioning from existing infrastructure to a new one. It specifies whether Terraform should first create a new resource and then delete the old one (true), or if it should delete the old resource first and then create the new one (false). This helps avoid interruptions in the operation of the infrastructure during updates or, in some cases, enables updates at all.
By default, if this argument is not specified, Terraform will first delete the resource and then create a new one. However, by using this argument, we can influence Terraform’s behavior. Setting the “create_before_destroy” flag to false looks like this in practice.
When you use this meta-argument in the “true” position, Terraform behaves differently and will first create object B and then remove the first one.
Real-life example
Let’s consider a specific use case where we have a simple infrastructure consisting of a single virtual machine along with an attached disk and a network interface. Due to the fact that the network interface was created with the wrong name, we are asked to recreate the interface without affecting the state of the virtual machine. As we know, renaming the network interface is a destructive operation, meaning that in order to perform it, the interface must be destroyed and then recreated. However, there’s also a virtual machine connected to this interface. The situation is further complicated by the fact that our organization strictly operates in a code-centric manner, and all manual operations are prohibited. Let’s try to perform this operation without using any arguments and try to understand what happened.
We change the name of the network interface in the code, run “init” and “plan” – everything looks good at this point, so we proceed with “apply.” Suddenly, we hit a roadblock. We receive an error informing us that it’s impossible to delete the network interface because it is associated with the virtual machine.
In this scenario, attempting to change the network interface’s name without specifying the necessary arguments led to an error due to the dependency between the interface and the virtual machine.
How to deal with such a problem? Well, the simplest way is to create a new network card, assign it to the virtual machine, and then remove the old one. Sound familiar? It’s precisely what the “create_before_destroy” lifecycle meta-argument does. Let’s apply this meta-argument in the code and see the result.
Once again, we run the plan and apply, and then we wait for the results. After a short while, we receive confirmation that the operation was successful. Let’s also have a look at the order in which Terraform handled the operation.
We can see that Terraform first created the network card, then modified the virtual machine to replace the card, and only in the final step began the operation to delete the old network card.
Summary
As you’ve seen in the above example, lifecycle metaarguments can be incredibly useful when managing infrastructure as code. Often, when writing Terraform configurations, we may overlook the management of the infrastructure’s lifecycle, which can lead to significant challenges. I hope that after reading this post, these challenges won’t be as daunting to you anymore.