The Three Stages of Terraform's Lifecycle Meta Argument (2024)

Every resource that is managed by Terraform has a lifecycle, this lifecycle contains three stages; Apply (Create), Update, and Destroy. The Apply stage is where the resource is actually created by Terraform, Update is when a change is made to a preexisting resource - this might be incremental or a full recreate - and finally Destroy where the resource is removed from the environment. Sometimes however we may want to control these stages of the resources lifecycle a little more for this Terraform gives us the lifecycle meta-argument.

The below diagram is a simple articulation of the three stages of the lifecycle at work!

The Three Stages of Terraform's Lifecycle Meta Argument (1)

What can we control?

As I have said above we can control - to some extent - the lifecycle further than the three above stages for our resources. Terraform gives us the following options that we can use in the lifecycle meta-argument:

  • create_before_destroy — when an in-place update has to occur Terraform will create the new instance prior to destroying the old
  • prevent_destroy — do not allow the destroy flow to actually destruct the resource
  • ignore_changes — ignore any changes on specified fields or an entire object
  • replace_triggered_by
  • precondition — check some thing before performing the action on the resource
  • postcondition — validate some thing after performing an action on the resource

We will go through most of these in a little more detail, although for the *condition you can check out this post.

Create Before Destroy

The create_before_destroy option is extremely useful in cases where the new instance of the resource must be there before destroy the old one. For example perhaps a public IP needs to be recreated but you don’t want the service to be inaccessible so you would ensure that the new address is created prior to the old one being destroyed.

Using the Scratch provider we can mock out an example of this:

resource "scratch_string" "this" { in = "create_before_destroy" lifecycle { create_before_destroy = true }}

The above will now ensure that in the event this resource is required to be replaced in- place that it will create the new instance first.

Prevent Destroy

prevent_destroy is another bool option which we can switch on, we would use this to ensure that Terraform never destroys the particular resource. On destroy the resource would be removed from state but still exist in the real world. This is useful in scenarios where perhaps not all your resources are managed by Terraform, or you do not want anyone to accidentally delete a particular resource.

Let’s dive into an example to better understand this concept.

resource "azurerm_resource_group" "this" { name = "rg-prod" location = "australiasoutheast" lifecycle { prevent_destroy = true }}

In the above we are creating a resource group, and we have informed Terraform we want to prevent its destruction through the lifecycle meta-argument. In this scenario let’s assume that we are only managing a portion of the resources within the resource group (RG) via Terraform and other via some other mechanism. If we were to not have prevent_destroy when we eventually did a destruction those resources created out of Terraform would also be destroyed. By having prevent_destroy we are now required to be more assertive when we want to destroy the RG, we would either have to remove it manually or commit a change removing the lifecycle attribute.

I find that prevent_destroy is a favourite to security folks as it helps to add an extra level of assurance around destructive operations, especially on resource types that have such a large blast area like a resource group.

Ignore Changes

Now we come to one of the more commonly used and in my opinion the most dangerous, ignore_changes. A reason why you might want to use ignore_changes is if some outside force / process is going to be modifying your resources, an example of this might be mutation of tags or tag values via Azure policy or potentially the number of instances of a resource due to a scaling event. Both of those examples are what I would consider good reasons to utilise ignore_changes. Lets look at a very basic example:

resource "scratch_block" "this" { in { string = "Meow" number = 42 bool = true } lifecycle { ignore_changes = [ in ] }}

In the above scratch_block we are ignoring any changes to the in block, and we cannot ignore a specific property on that block as the block is actually represented as a set which does not have an index or referenceable value. It is important to note that the values provided here must be static, you cannot pass in a variable or a splat. The only exception is the use of the special all keyword in place of a list which will then ignore all attributes on the resource.

ignore_changes becomes dangerous when you start ignoring entire resources as then changes you make to the code won’t alter the resource this means you’re only managing two stages of the resource Apply and Destroy all alteration would then have to be managed by an external system.

Many organisations uses tags for managing or attributing cost with cloud resources so ignore changing to particular tags or the tags property can be very valuable as it allows an external system to manage the tags on resources for you without Terraform overwriting the changes. When using ignore_changes my advice to be as specific about the property you’re wanting to ignore as you possibly can be!

Replace Triggered By

replace_triggered_by is a very new addition to language, only coming out with Terraform v1.2, it is also a very powerful argument. This will replace a particular resource based on another resource. Below is an example:

resource "scratch_bool" "this" { in = false}resource "scratch_string" "this" { in = "create_before_destroy" lifecycle { replace_triggered_by = [ scratch_bool.this ] }}

In the above example we have two resources scratch_bool.this and scratch_string.this we are tying a replace to the scratch_boo.this. What this means is that if we were to update scratch_bool.this.in to be true the entire scratch_string.this resource would be replaced!

This allows us to create really tight dependancies on resources that may not be otherwise related in our Terraform code. You should however be very careful using this as if the referenced resource changes then your resource will be replaced.

Final Thoughts

So that closes out the options we can implement to augment the standard lifecycle state within Terraform. Altering the lifecycle allows for some very powerful control over our resources but it does come with risk, when you’re making further changes to resources you have to ensure that you’ve considered what could happen based on any lifecycle modifications you’ve made.

I am very interested to see what additional things HashiCorp come out with in the lifecycle realm!

You can follow Brendan @BrendanLiamT on Twitter.

Note: While this blog references Terraform, everything mentioned in here also applies to OpenTofu. New to OpenTofu? It is a fork of Terraform 1.5.7 as a result of the license change from MPL to BUSL by HashiCorp. OpenTofu is an open-source alternative to Terraform that is governed by the Linux Foundation. All features available in Terraform 1.5.7 or earlier are also available in OpenTofu. Find out the history of OpenTofu here.

The Three Stages of Terraform's Lifecycle Meta Argument (2024)
Top Articles
IBC Code
Exogenous causes are factors that influence the business cycle from outside of the system, e.g. climate (drought and other natural disasters) and the political situation of a country. Endogenous causes are factors that influence the business cycle from i
Aberration Surface Entrances
123 Movies Black Adam
Le Blanc Los Cabos - Los Cabos – Le Blanc Spa Resort Adults-Only All Inclusive
Ghosted Imdb Parents Guide
Collision Masters Fairbanks
360 Training Alcohol Final Exam Answers
What happens if I deposit a bounced check?
Kent And Pelczar Obituaries
Derpixon Kemono
How do you like playing as an antagonist? - Goonstation Forums
Evil Dead Rise Showtimes Near Regal Columbiana Grande
Hijab Hookup Trendy
2021 Lexus IS for sale - Richardson, TX - craigslist
No Hard Feelings Showtimes Near Cinemark At Harlingen
Arboristsite Forum Chainsaw
Panorama Charter Portal
Aucklanders brace for gales, hail, cold temperatures, possible blackouts; snow falls in Chch
Locate At&T Store Near Me
Libinick
Understanding Genetics
How many days until 12 December - Calendarr
All Breed Database
Okc Body Rub
Gas Buddy Prices Near Me Zip Code
Riversweeps Admin Login
Play Tetris Mind Bender
Mynahealthcare Login
Roseann Marie Messina · 15800 Detroit Ave, Suite D, Lakewood, OH 44107-3748 · Lay Midwife
Penn State Service Management
Rainfall Map Oklahoma
49S Results Coral
Renfield Showtimes Near Marquee Cinemas - Wakefield 12
The Latest: Trump addresses apparent assassination attempt on X
Salons Open Near Me Today
Grapes And Hops Festival Jamestown Ny
Elgin Il Building Department
Unifi Vlan Only Network
Cdcs Rochester
Lake Andes Buy Sell Trade
Ferguson Showroom West Chester Pa
Amc.santa Anita
Jaefeetz
Ghareeb Nawaz Texas Menu
VerTRIO Comfort MHR 1800 - 3 Standen Elektrische Kachel - Hoog Capaciteit Carbon... | bol
Learn4Good Job Posting
Richard Mccroskey Crime Scene Photos
Grace Family Church Land O Lakes
The Hardest Quests in Old School RuneScape (Ranked) – FandomSpot
Diamond Desires Nyc
Supervisor-Managing Your Teams Risk – 3455 questions with correct answers
Latest Posts
Article information

Author: Terence Hammes MD

Last Updated:

Views: 6326

Rating: 4.9 / 5 (69 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Terence Hammes MD

Birthday: 1992-04-11

Address: Suite 408 9446 Mercy Mews, West Roxie, CT 04904

Phone: +50312511349175

Job: Product Consulting Liaison

Hobby: Jogging, Motor sports, Nordic skating, Jigsaw puzzles, Bird watching, Nordic skating, Sculpting

Introduction: My name is Terence Hammes MD, I am a inexpensive, energetic, jolly, faithful, cheerful, proud, rich person who loves writing and wants to share my knowledge and understanding with you.