How to use Terraform resource meta arguments?


Terraform resource Meta-Arguments can be useful while setting up your cloud infrastructure. The resource arguments depends_on, count, for_Each, provider, lifecycle has some features such as -

  1. You can create multiple aws_resource using the count
  2. for_each can be used for iteration and can also help you to create multiple aws_resource using the same block
  3. provider is used for overriding terraform default behavior using the alias
  4. With lifecycle you can prevent destroy, create resource after destroy and ignore changes to be saved inside tstate

We will look into each resource meta arguments in a bit more details along with the example -

Table of Content

  1. count
  2. for_each
  3. provider
  4. lifecycle


1. Count

As the name suggests count can be used inside the aws_instance block to specify how many resources you would like to create.

Here is an example in which we are going to spin 2 aws_instance -

 1provider "aws" {
 2   region     = "eu-central-1"
 3   access_key = "AKIATQ37NXB2HS7IVM5R"
 4   secret_key = "MJy5JX6HIqHwP9gLAv+22kffS/jiDsMo2XLP9mZn"
 5}
 6
 7resource "aws_instance" "ec2_example" {
 8
 9   count         = 2 
10   ami           = "ami-0767046d1677be5a0"
11   instance_type =  "t2.micro"
12
13   tags = {
14           Name = "Terraform EC2"
15   }
16}

Benefit of Count: -

  1. You do not need to write the same resource block again if you want to create more than one resource.

  2. It can also be used with modules and any kind of resource type available in terraform.



2. for_each

Similar to the previous step 1 for_each can also be used for creating similar kinds of resources instead of creating a writing duplicate terraform block.

Here is one more example of terraforming block with for_each -

 1provider "aws" {
 2   region     = "eu-central-1"
 3   access_key = "AKIATQ37NXB2HS7IVM5R"
 4   secret_key = "MJy5JX6HIqHwP9gLAv+22kffS/jiDsMo2XLP9mZn"
 5}
 6
 7resource "aws_instance" "ec2_example" {
 8
 9    for_each = {
10      instance1 = "t2.micro"
11      instance2 = "t2.micro" 
12    }
13
14   ami           = "ami-0767046d1677be5a0"
15   instance_type =  each.value
16
17   tags = {
18           Name = "Terraform ${each.key}"
19   }
20} 

As you can see in the above terraform block we have created 2 key-value pair instance1 = t2.micro and instance2 = t2.micro inside the for_each block.

The next question is how to use key-value pair defined inside for_each?

The answer - It is very simple you can just simply type each.value and it will iterate over the values.

Here is a screenshot from aws after starting the aws_instance

Terraform resource meta arguments for_each



3. provider

This meta argument is one of my favorite because it lets you override Terraform's default behavior. It can help you to create multiple configurations for a single cloud service provider (.e.g - AWS, GCP).

One simple example would be - "Suppose you want to create two aws_instance one in eu-central-1 and another one in eu-nort-1 region, would it be possible for you to create in single main.tf file?"

Well, YES you can do that but to achieve this you need to use provider inside your terraform file along with the alias.

Here are the steps for using provider meta argument -

Step 1 - First create a simple provider block in your terraform file -

1provider "aws" {
2   region     = "eu-central-1"
3   access_key = "AKIATQ37NXB2HS7IVM5R"
4   secret_key = "MJy5JX6HIqHwP9gLAv+22kffS/jiDsMo2XLP9mZn"
5}

Step 2 - Create a one more provider block but with an additional argument alias

1provider "aws" {
2  alias  = "north"
3  region = "eu-north-1"
4  access_key = "AKIATQ37NXB2HS7IVM5R"
5  secret_key = "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"
6}

Step 3 - Here is the final terraform file in which we are going to create 2 aws instance with one in eu-north-1 region and another in eu-central-1 region -

 1provider "aws" {
 2  alias  = "north"
 3  region = "eu-north-1"
 4  access_key = "AKIATQ37NXB2HS7IVM5R"
 5  secret_key = "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"
 6}
 7
 8provider "aws" {
 9   region     = "eu-central-1"
10   access_key = "AKIATQ37NXB2HS7IVM5R"
11   secret_key = "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"
12}
13
14resource "aws_instance" "ec2_eu_north" {
15   provider      = aws.north
16   ami           = "ami-0ff338189efb7ed37"
17   instance_type =  "t3.micro"
18   count = 1
19   tags = {
20           Name = "Terraform EC2"
21   }
22
23}
24
25resource "aws_instance" "ec2_eu_central" {
26   ami           = "ami-0767046d1677be5a0"
27   instance_type =  "t2.micro"
28   count = 1
29   tags = {
30           Name = "Terraform EC2"
31   }
32}

So as you can see provider with alias can be useful in case you want to spin/start multiple instances in the different regions of your cloud service provider.



4. lifecycle

This meta argument is a lifesaver if you are working in the production environment where you have to be very careful so that you do not accidentally destroy any resource.

With lifecyle meta tag you can make sure that certain resources should not be deleted and you can also create a new similar resource after the terraform destroy command.

There are three arguments which you can pass inside the lifecycle block -

  1. create_before_destroy - Once you set this argument the resource will be created once again after you issue the terraform destroy command
  2. prevent_destroy - It prevents from destroying your terraform resource, once you set this terraform argument then the resource can not be destroyed
  3. ignore_changes - Suppose you have manually made some changes on aws or GCP but you want to prevent those changes to be saved inside your terraform terraform.tfstate file then you can use ignore_changes arguments.

Here is the sample code snippet (Please uncomment the arguments as per your need) -

 1provider "aws" {
 2   region     = "eu-central-1"
 3   access_key = "AKIATQ37NXB2HS7IVM5R"
 4   secret_key = "MJy5JX6HIqHwP9gLAv+22kffS/jiDsMo2XLP9mZn"
 5}
 6
 7resource "aws_instance" "ec2_example" {
 8
 9   count         = 2 
10   ami           = "ami-0767046d1677be5a0"
11   instance_type =  "t2.micro"
12
13   tags = {
14           Name = "Terraform EC2"
15   }
16   
17       lifecycle {
18      create_before_destroy = true
19      #prevent_destroy       = true
20      #ignore_changes        = [tags]
21   }
22}



Read More - Terragrunt -

  1. How to use Terragrunt?

Posts in this Series