Day 69  Meta-Arguments in Terraform

Day 69 Meta-Arguments in Terraform

Day 69 of #90daysofdevops

Hey Techies! Welcome to this blog

In this blog, we are going to start with Meta-Arguments in Terraform.

Meta-arguments in Terraform are special arguments that can be used with resource blocks and modules to control their behavior or influence the infrastructure provisioning process. They provide additional configuration options beyond the regular resource-specific arguments.

Meta-Arguments in Terraform are as follows:

  1. depends_on: Specifies dependencies between resources. It ensures that one resource is created or updated before another resource.

  2. count: Controls resource intantiation by setting the number of instances created based on a given condition or variable.

  3. for_each: Allows creating multiple instances of a resource based on a map or set of strings. Each instance is created with its unique key-value pair.

  4. lifecycle: Defines lifecycle rules for managing resource updates, replacements, and deletions.

  5. provider: Specifies the provider configuration for a resource. It allows selecting a specific provider or version for a resource.

  6. provisioner: Specifies actions to be taken on a resource after creation, such as running scripts or executing commands.

  7. connection: Defines the connection details to a resource, enabling remote execution or file transfers.

  8. variable: Declares input variables that can be provided during Terraform execution.

  9. output: Declares output values that can be displayed after Terraform execution.

  10. locals: Defines local values that can be used within the configuration files.

What is meta-arguments and its use in Terraform?

Meta-arguments in Terraform are special arguments that provide additional functionality and control over resource configuration. They are used to define how resources are managed and interacted with in a broader context.

The use of meta-arguments in Terraform offers several benefits:

1. Dependency management: The depends_on meta-argument allows you to specify explicit dependencies between resources, ensuring the correct order of resource creation or modification.

2. Dynamic resource creation: The count meta-argument enables the creation of multiple resource instances based on a specified value or condition, making it easier to manage resources at scale.

3. Provider selection: The provider meta-argument allows you to choose a specific provider configuration for a resource, useful when working with multiple providers or different configurations of the same provider.

4. Lifecycle management: The lifecycle meta-argument provides control over resource lifecycle, including options like create_before_destroy and prevent_destroy to manage resource creation, modification, and destruction behavior.

5. Provisioning: The provisioner meta-argument allows you to define actions to be performed on a resource after creation or update, such as running scripts or executing commands for resource configuration.

6. Configuration flexibility: The variable meta-argument is used to define input variables that can be used to parameterize Terraform configurations, enhancing flexibility and reusability.

Meta-arguments in Terraform provide advanced capabilities to control and customize your modules or resources. These special arguments enable you to define dependencies, configure options, and enhance the flexibility of your Terraform code. By leveraging meta-arguments, you can fine-tune your configurations and tailor them to your specific needs, ensuring that your Terraform code aligns perfectly with your desired infrastructure state.

Count

The count meta-argument is used to create a specified number of resource instances. Each instance has its own unique infrastructure object, enabling separate management for each. Let's demonstrate this with an example:

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 = 4

  ami           = "ami-08c40ec9ead489470"
  instance_type = "t2.micro"

  tags = {
    Name = "Server ${count.index}"
  }
}

In this example, we create four AWS instances using the specified Amazon Machine Image (AMI) and instance type. The count.index is used to generate unique names for each instance.

for_each

The for_each meta-argument, similar to count, creates multiple instances of a resource block. However, instead of specifying the number of resources, for_each accepts a map or a set of strings. This is useful when different resources require distinct values. Let's explore this with an example:

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-0b0dcb5067f052a63",
    "ami-08c40ec9ead489470",
  ])
}

resource "aws_instance" "server" {
  for_each = local.ami_ids

  ami           = each.key
  instance_type = "t2.micro"

  tags = {
    Name = "Server ${each.key}"
  }
}

In this example, we create instances based on unique AMI IDs from the local.ami_ids set. The each.key is used to set the AMI ID dynamically, resulting in servers with distinct configurations.

Now, let's implement the above Infrastructure as Code (IaC) and demonstrate the use of count and for_each.

Task

Create the Terraform Configuration

Save the following code in a file named main.tf:

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "count_example" {
  count = 4

  ami           = "ami-08c40ec9ead489470"
  instance_type = "t2.micro"

  tags = {
    Name = "Server ${count.index}"
  }
}

locals {
  ami_ids = toset([
    "ami-0b0dcb5067f052a63",
    "ami-08c40ec9ead489470",
  ])
}

resource "aws_instance" "for_each_example" {
  for_each = local.ami_ids

  ami           = each.key
  instance_type = "t2.micro"

  tags = {
    Name = "Server ${each.key}"
  }
}

Initialize and Apply the Configuration

Run the following commands in your terminal:

terraform init
terraform apply

Follow the prompts to confirm the changes.

Verify the Results

After the configuration is applied, you should see four instances created using the count meta-argument and instances based on unique AMI IDs using the for_each meta-argument.

Congratulations! You've successfully demonstrated the use of count and for_each meta-arguments in Terraform.

Some More Meta-Arguments

depends_on

The depends_on meta-argument is used to explicitly define dependencies between resources. Terraform automatically figures out the order of resource creation based on the dependencies, but in some cases, you might need to explicitly specify dependencies.

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

  depends_on = [aws_s3_bucket.example]
}

In this example, the aws_instance resource depends on the creation of the aws_s3_bucket resource.

lifecycle

The lifecycle meta-argument allows you to define various settings related to the lifecycle of a resource. For example, you can prevent certain resources from being destroyed or updated under specific conditions.

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

  lifecycle {
    prevent_destroy = true
  }
}

In this example, the prevent_destroy setting ensures that the aws_instance resource cannot be destroyed.

provisioner

The provisioner meta-argument enables you to execute scripts or other configuration management tools on the provisioned instances. This can be particularly useful for tasks such as installing software, configuring services, or customizing the environment based on your specific requirements.

Thank you so much for taking the time to read till the end! Hope you found this blog informative and helpful.

Feel free to explore more of my content, and don't hesitate to reach out if need any assistance from me or in case of you have any questions.

Happy Learning!

~kritika :)

Connect with me: LinkedIn