Day 69 - Meta-Arguments in Terraform
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.
eg.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-east-2"
}
resource "aws_instance" "server" {
count = 3
ami = "ami-02bf8ce06a8ed6092 "
instance_type = "t2.micro"
tags = {
Name = "Server ${count.index}"
}
}
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.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-east-2"
}
locals {
ami_ids = toset([
"ami-02bf8ce06a8ed6092",
"ami-09040d770ffe2224f",
])
}
resource "aws_instance" "server" {
for_each = local.ami_ids
ami = each.key
instance_type = "t2.micro"
tags = {
Name = "Server ${each.key}"
}
}
Multiple key value iteration
locals {
ami_ids = {
"linux" :"ami-02bf8ce06a8ed6092 ",
"ubuntu": "ami-09040d770ffe2224f",
}
}
resource "aws_instance" "server" {
for_each = local.ami_ids
ami = each.value
instance_type = "t2.micro"
tags = {
Name = "Server ${each.key}"
}
}
Task-01
Create the above Infrastructure as code and demonstrate the use of Count and for_each.
Meta argument- count
The first section of the code is the "terraform" block. Here, we specify the required version of Terraform, as well as the required providers. In this case, we are specifying that we require the AWS provider, and that it should be sourced from the "hashicorp/aws" module with a version greater than or equal to 4.16.
Next, we define the "provider" block, which specifies the configuration for the AWS provider. In this case, we are specifying the region as us-east-2.
The "aws_instance" resource block, which creates the EC2 instances. The "count" meta-argument is used to create four instances, each with the specified AMI and instance type. The "tags" block is used to assign a name to each instance, with a unique index based on the count.
Run terraform init to initialize the Terraform project.
Run terraform plan
Run terraform apply to create a 3 instances.
Three new EC2 instances successfully created.
Meta argument - for_each
We define a "locals" block to create a set of AMI IDs for our instances. We use the "toset" function to convert an array of strings into a set of strings.
In the "resource" block, we define the "aws_instance" resource and use the "for_each" meta-argument to create an instance for each AMI ID in our "ami_ids" map. The "ami" attribute is set to the current key in the map (i.e., the AMI ID), and the "instance_type" attribute is set to "t2.micro". We also use the "tags" attribute to set a unique name for each instance using the current key in the map.
Run terraform apply
Two new instances successfully created.
With multiple key-value iteration.
We use the "for_each" meta-argument with a map that has multiple key-value pairs to create instances with different AMIs. In this case, we use a map with two key-value pairs, where each key is a string that represents the name of the AMI, and each value is the actual AMI ID.
Inside the "resource" block, we use the "each.value" variable to access the current value in the map (i.e., the AMI ID), and set the "ami" attribute to it. We also use the "each.key" variable to access the current key in the map (i.e., the AMI name), and use it to set a unique name for each instance using the "tags" attribute.
Using the "for_each" meta-argument with maps can be very useful for creating multiple instances with different configurations in a single block of code.
Run terraform apply
Two new instances created using 'for_each' meta argument
Write about meta-arguments and its use in Terraform.
Meta-arguments are special arguments in Terraform that are used to control how resources are created, updated, or destroyed. They are not specific to any particular resource type, but rather provide a way to configure behavior across all resources in a Terraform configuration.
The main use of meta-arguments in Terraform is to control the dependencies between resources. For example, the "depends_on" meta-argument can be used to specify that a resource depends on another resource. This can be useful when creating resources that require other resources to exist first, such as a load balancer that depends on an auto scaling group.
Another common use of meta-arguments is to control the order in which resources are created. The "count" and "for_each" meta-arguments can be used to create multiple instances of a resource, and the "lifecycle" meta-argument can be used to control when resources are created, updated, or destroyed.
The "provider" meta-argument is also a very important meta-argument in Terraform. It is used to specify the provider that should be used to manage a particular resource. Providers are plugins that Terraform uses to manage resources, such as AWS, Google Cloud, or Azure.
Overall, meta-arguments are a powerful feature of Terraform that can be used to control the behavior of resources in a flexible and granular way. By using meta-arguments effectively, Terraform users can create more robust and scalable infrastructure as code.
Thank you for reading!
Subscribe to my newsletter
Read articles from Nikhil Yadav directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Nikhil Yadav
Nikhil Yadav
I am a highly motivated and enthusiastic individual completed B.Tech from Savitribai Phule University, Pune . With a strong interest in DevOps and Cloud technologies, I am eager to kick-start my career in this domain. Although I do not have much professional experience, I possess a willingness to learn, excellent problem-solving skills, and a passion for technology. I am committed to contributing my best to any team I work with.