Terraform Lifecycle: Workflow and Lifecycle Meta-Argument

Blog Featured image for a blog with a title - Terraform lifecycle

Terraform Lifecycle: Workflow and Lifecycle Meta-Argument

Blog Featured image for a blog with a title - Terraform lifecycle
Categories

Introduction

IaC has transformed how we think of building and managing infrastructure. The days of hand-configured servers and dragging through murky cloud dashboards are long gone. Infrastructures (servers, databases, networks, etc.) can be defined using tools such as Terraform in simple, easy-to-read configuration files.

While many users are familiar with the init, plan, and apply workflow, the real magic happens in a deeper process: the Terraform Lifecycle or Terraform Resource Lifecycle. This isn’t the sequence of commands you run; it’s the internal set of stages that every single resource goes through as managed by Terraform’s engine: Create, Update, and Destroy. Understanding this internal lifecycle in Terraform is the key to mastering Terraform. It enables you to move beyond simply running commands and start managing complex infrastructure with confidence, thereby preventing errors such as accidental database deletion or unnecessary service downtime.

In this blog, we will explore the true Terraform Resource Lifecycle in detail. We’ll examine the core actions Terraform takes on your resources and then dive into the powerful lifecycle meta-argument, which gives you granular control over this entire process.

What is Terraform Lifecycle?

The Terraform Lifecycle is the journey a resource takes as Terraform creates, updates, and ultimately destroys it to keep your real-world infrastructure perfectly in sync with your code.

Why care about the Terraform lifecycle? Because infrastructure isn’t static. It evolves. Resources get created, updated, or removed. Knowledge of the lifecycle in Terraform can avoid errors such as accidentally deleting a production database.

The entire process is centred on a core principle: maintaining consistency between your configuration files and the state of your real-world infrastructure.

Before exploring the different stages of the Terraform Resource Lifecycle, let us understand the Terraform Workflow for better Comprehension, as many users get confused between the Terraform workflow and the Terraform lifecycle.

Terraform Workflow

Terraform workflow is associated with the four main commands that you will use regularly-

terraform workflow
  • terraform init (Preparation)
  • terraform plan (Planning/Review)
  • terraform apply (Execution)
  • terraform destroy (Destruction)

The foundation of the entire workflow is a fundamental element, i.e., the Terraform state file. This file, called terraform.tfstate, is typically a JSON record of what Terraform is managing. It is the memory of Terraform and keeps track of the resource mapping between your code and the actual resources of your cloud provider. The workflow is fluidic communication between your code, the state file and the real world.

Let’s understand each stage in detail.

Stage 1: Initialization (terraform init)

Before you can build anything, you need to prepare your workspace. The terraform init command will be the first command you use in any Terraform project. It does not modify your infrastructure, but it can perform several essential setup tasks to prepare your local environment. This command must be run once at the beginning of a new project or when you modify your providers or modules.

Stage 2: Planning (terraform plan)

This is by far the most significant stage in the Terraform workflow. It is to ensure both safety and predictability are met. The terraform plan command is just a dry run. It provides a preview of what Terraform would change in your infrastructure, should you apply the changes, without actually making those changes.

How does it generate this plan? It’s a three-step process:

  • Reads Your Code: Terraform parses all of your .tf files to derive a model of what you desire. This is how your infrastructure should be.
  • Reads the State File: It reads the terraform.tfstate file, which attempts to determine the current state, or what it believes the infrastructure to be based on last time the file was run.
  • Checks Real World: It then issues API calls to your cloud provider to update its knowledge that the state file is not out of sync with reality. For example, it verifies whether a server stored in the state file still exists.

Once this information is acquired, Terraform then compares the desired state (code) against the refreshed current state. The distinction between the two becomes the execution plan.

Stage 3: Application (terraform apply)

Once you have reviewed the plan and feel comfortable with the changes you have suggested, it is time to implement them. terraform apply is the command that runs the plan and makes your infrastructure the way you desire it to be, i.e., the desired state.

There are two main ways of running this command:

  • Interactive Apply: Simply run ‘terraform apply’. Terraform will create a plan as it goes and display it to you, followed by a prompt asking you to approve. You must type ‘yes’ to continue. That is wonderful when you want to do manual work on your local machine.
  • Execution of a Saved Plan: terraform apply “tfplan”. This command loads the plan file you have previously built into memory and executes it without further prompting. This is the only secure method for executing Terraform within an automated pipeline. It ensures that only reviewed and approved changes can be applied.

Stage 4: Destruction (terraform destroy)

The final stage in the workflow is destroying everything. The terraform destroy command is utilized in deleting all the infrastructure managed by your Terraform project.

It works the same as apply, but in the reverse order. When you execute it, Terraform will use your state file to determine what it manages, build a plan to destroy everything it operates, and ask for your approval. It also follows the dependency graph, removing virtual machines before removing the subnets they are in.

What are Terraform Resources?

In Terraform, a “resource” is the most fundamental element. It represents a component of your infrastructure, like a virtual machine, a DNS record, or a database.

Defining a Resource

A resource block defines a piece of infrastructure. It has a type (e.g., aws_instance) and a local name (e.g., web_server).

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "MyWebServer"
  }
}

Terraform Resource Lifecycle: A step-by-step Breakdown

The Terraform Resource Lifecycle, also known as the Terraform lifecycle, is the sequence of actions that Terraform performs on a single resource from the moment it’s defined in your code until it is removed. This process involves comparing your configuration files against the Terraform state file and the actual infrastructure.

There are three primary actions in a resource’s lifecycle:

Create

When a resource is defined in your code but doesn’t exist in the state file or the cloud provider, Terraform plans to create it.

Update

When a resource already exists but an argument in your code has changed, Terraform plans an update. This can happen in two ways:

  • Update in-place: For changes that don’t require recreating the resource (e.g., changing a server’s tags), the provider API can modify it directly.
  • Destroy and Recreate: For significant changes (e.g., changing an EC2 instance type), Terraform must destroy the old resource and create a new one to apply the change.

Destroy

When a resource is removed from your code but still exists in the state file, Terraform plans to destroy it.

Now that we have a good understanding of resources in Terraform and the Terraform Lifecycle, let’s discuss Terraform lifecycle meta-arguments.

Customizing the Terraform Lifecycle: Terraform Lifecycle Meta-Arguments

The standard Terraform lifecycle works brilliantly for most use cases, but sometimes you need more granular control. Terraform provides a special lifecycle configuration block that you can place inside any resource block to change its behavior.

This is an advanced feature, but three of its arguments are particularly useful.

create_before_destroy

By default, when one of the resources has to be replaced (such as changing the EC2 instance type), Terraform will destroy the old resource first and then create a new one. This can result in down time

By setting create_before_destroy = true, what you are telling Terraform is to do the opposite. It will first provision the new resource, and only after it once successfully created will then destroy the old one. It is an easy method of minimizing or removing downtime during updates on services such as load balancers or virtual machines.

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  lifecycle {
    create_before_destroy = true
  }
}

prevent_destroy

Some resources are so critical that you want to protect them from accidental deletion. Think of your primary production database. If you set prevent_destroy = true on that resource, Terraform will refuse to destroy it. Any plan or apply that includes the destruction of this resource will fail with an error. This is a fantastic safety net to prevent catastrophic mistakes.

resource "aws_db_instance" "production_db" {
  # ... database configuration ...

  lifecycle {
    prevent_destroy = true
  }
}

ignore_changes

In some cases, you need to use Terraform to manage a resource, but do not want Terraform to manage all attributes of that resource. For example, you may have an auto-scaling group of servers that requires configuration management using Terraform. However, the desired_capacity of such a group may be managed by an automated scaling policy, not your code.

If you set the desired_capacity in your code, every time the scaling policy changes it, the next terraform plan will attempt to revert it. The ignore_changes argument tells Terraform to ignore specific attributes, effectively handing over control of them to an external process.

resource "aws_autoscaling_group" "web_asg" {
  # ... other configuration ...
  desired_capacity = 2

  lifecycle {
    ignore_changes = [
      # Terraform will no longer manage the desired_capacity
      # after the initial creation.
      desired_capacity,
    ]
  }
}

replace_triggered_by

Some changes don’t directly affect a resource’s arguments, but you still want them to trigger a replacement. For example, you might want to replace an EC2 instance whenever its startup script file changes.

The replace_triggered_by argument forces a resource to be replaced when another specified resource or value changes.

This is often used with a null_resource that tracks a file’s hash.

resource "null_resource" "startup_script" {
  triggers = {
    script_hash = filemd5("${path.module}/scripts/setup.sh")
  }
}

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  
  # Pass the script hash to the user data or an environment variable
  user_data = file("${path.module}/scripts/setup.sh")

  lifecycle {
    replace_triggered_by = [
      # If the script's hash changes, replace this instance
      null_resource.startup_script,
    ]
  }
}

In this example, filemd5() calculates the MD5 hash of the setup.sh script. If that script is modified in any way, its hash will change. This change in null_resource.startup_script will trigger a replacement of the aws_instance.web_server, ensuring your server is always running the latest version of your startup script.

Frequently Asked Questions

Q1. What are the 4 stages of Terraform?

Terraform’s core workflow has four stages. init prepares your workspace. plan previews the changes. apply executes the planned actions, and destroy is used to remove all managed infrastructure.

Q2 What are the 5 steps of Terraform?

A typical Terraform workflow has five steps. You first write the configuration code, then run init to prepare. Next, you plan, review, apply the changes, and then destroy.

Q3. Is Terraform an ETL tool?

No, Terraform is not an ETL tool. ETL (Extract, Transform, Load) tools are for managing data pipelines. Terraform is an Infrastructure as Code (IaC) tool for provisioning infrastructure resources.

Q4. When to use ${} in Terraform?

The ${} syntax is used for string interpolation, allowing the embedding of expressions or variables within a string. In modern Terraform, it’s optional for simple variables but still required for more complex expressions.

Conclusion

Terraform Lifecycle is not a series of commands. It brings the predictability, safety and repeatability of software development into infrastructure management. The method of initialization, planning, and application is a sequence of actions that eliminates speculation and human error. The user workflow, i.e., init, plan, apply, and destroy, is the engine that drives the resource lifecycle. Taking an Ansible and Terraform course can help users better understand and implement this workflow effectively. This flow, along with the ability to modify it using Terraform lifecycle meta-arguments, is the difference between a beginner and an advanced Terraform user. It is the baseline to all trusted, assisted and expandable infrastructure.

Get in touch

Blog
Looking For Networking Training- PyNetLabs

Popular Courses

Automation

(FRESHERS / EXPERIENCED)

Network Expert

Automation

(FRESHERS / EXPERIENCED)

Network Expert

Automation

(FRESHERS / EXPERIENCED)

Network Expert

Automation

(FRESHERS / EXPERIENCED)

Network Expert

Automation

(FRESHERS / EXPERIENCED)

Network Expert

Leave a Reply

Your email address will not be published. Required fields are marked *