Meta-Arguments in Terraform

Meta-Arguments in Terraform

Day 69 of 90daysofdevops

What are Meta-Arguments in Terraform

  • meta-arguments are special arguments used to modify the behavior of resources or blocks. They provide additional functionality beyond the standard resource configuration.

  • Meta-arguments allow you to customize resource behavior, define dependencies between resources, control resource lifecycle, and associate providers with resources or blocks.

  • When you define a resource block in Terraform, by default, this specifies one resource that will be created. To manage several of the same resources, you can use either count or for_each, which removes the need to write a separate block of code for each one.

  • Using these options reduces overhead and makes your code neater. count is what is known as a ‘meta-argument’ defined by the Terraform language. Meta-arguments help achieve certain requirements within the resource block.

count

The count meta-argument accepts a whole number and creates the number of instances of the resource specified.

When each instance is created, it has its own distinct infrastructure object associated with it, so each can be managed separately. When the configuration is applied, each object can be created, destroyed, or updated as appropriate.

for_each

Like the count argument, the for_each meta-argument creates multiple instances of a module or resource block. However, instead of specifying the number of resources, the for_each meta-argument accepts a map or a set of strings.

This is useful when multiple resources are required that have different values. Consider our active directory groups example, with each group requiring a different owner.

Use cases of meta arguments

  1. Dynamic resource creation: Use "count" to create a variable number of instances based on conditions.

  2. Managing dependencies: "depends_on" ensures resources are created or modified in the correct order.

  3. Fine-grained lifecycle management: "lifecycle" controls resource behavior during updates or replacements.

  4. Multi-cloud provider support: "provider" associates different providers with specific resources, enabling multi-cloud management.

  5. Custom provisioning and configuration: "provisioner" executes scripts or commands during resource creation or destruction, allowing custom actions.


Task- 1: Create the above IaC and use "count" and "for_each".

Meta Argument: count

  • Create a main.tf and pass the details of AWS providers and aws instance details. Using the count meta argument you can name the instances as per the number of counts you have passed on.

      terraform {
        required_providers {
           aws = {
              source = "hashicorp/aws"
              version = "~> 4.16"
          }
       }
       required_version = ">= 1.2.0"
      } 
    
      provider "aws" {
         region = "us-east-1"
      }
    
      resource "aws_instance" "server" {
           count = 2
           ami = "ami-053b0d53c279acc90"
           instance_type = "t2.micro"
           tags = {
              Name = "Server ${count.index}"
          }
      }
    
  • Run terraform init to initialize the Terraform project.

  • Execute the terraform plan command.

  • Execute the terraform apply to create 2 new EC2 instances.

  • You can verify, 2 new EC2 instances were successfully created and named as per the count argument.

Meta argument: for_each

  • Create a main.tf and pass the details of AWS providers and aws instance details. Using the for_each meta argument you can name the instances as per iteration of the locals ami ids.

      terraform {
        required_providers {
           aws = {
              source = "hashicorp/aws"
              version = "~> 4.16"
          }
       }
       required_version = ">= 1.2.0"
      } 
    
      provider "aws" {
         region = "us-east-1"
      }
    
      locals {
          ami_ids = toset([
              "ami-022e1a32d3f742bd8",
              "ami-053b0d53c279acc90",
           ])
      }
    
      resource "aws_instance" "server" {
         for_each = local.ami_ids
            ami = each.value
            instance_type = "t2.micro"  
         tags = {
            Name = "Server ${each.key}"
         }
      }
    
  • Execute the terraform apply to create 2 new EC2 instances.

  • 2 new instances were successfully created and named after ami id as we are using for_each.

Meta argument: multiple key-value iterations.

  • Create a main.tf and pass the details of AWS providers and aws instance details. Using the for_each meta argument you can name the instances as per iteration of the locals ami ids but here we are passing both key: value pairs.

    
      terraform {
        required_providers {
           aws = {
              source = "hashicorp/aws"
              version = "~> 4.16"
          }
       }
       required_version = ">= 1.2.0"
      } 
    
      provider "aws" {
         region = "us-east-1"
      }
    
      # Multiple key value iteration
      locals {
        ami_ids = {
          "amazonlinux" :"ami-022e1a32d3f742bd8",
          "ubuntu": "ami-053b0d53c279acc90",
         }
      }
    
      resource "aws_instance" "server" {
         for_each = local.ami_ids
            ami = each.value
            instance_type = "t2.micro"  
         tags = {
            Name = "Server ${each.key}"
         }
      }
    
  • Execute the terraform apply to create 2 new instances.

  • Two new instances were successfully created by taking the name using key values of ami ids.


Thank You,

I want to express my deepest gratitude to each and every one of you who has taken the time to read, engage, and support my journey.

Feel free to reach out to me if any corrections or add-ons are required on blogs. Your feedback is always welcome & appreciated.

~ Abhisek Moharana 🙂