Terraform meta-arguments (Part 4)

Enthusiastic about DevOps tools like Docker, Kubernetes, Maven, Nagios, Chef, and Ansible and currently learning and gaining experience by doing some hands-on projects on these tools. Also, started learning about AWS and GCP (Cloud Computing Platforms).
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
Count: Controls resource instantiation by setting the number of instances created based on a given condition or variable.
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
depends on: Specifies dependencies between resources. It ensures that one resource is created or updated before another resource.
lifecycle: Defines lifecycle rules for managing resource updates, replacements, and deletions.
Count
Let’s first create a recap through creating 4 instances in AWS
Create a folder
mkdir terraform-meta
cd terraform-meta
Now write the HCL file for the provisioning
# vi main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "ap-south-1"
}
resource "aws_instance" "terraform" {
count = 4
ami = "ami-0dee22c13ea7a9a67"
instance_type = "t2.micro"
tags = {
Name = "terraform-instance"
}
}
But if we apply this code this create 4 instances with same name which is a problem between developers and tester. To solve this problem let’s use count index.
# vi main.tf
resource "aws_instance" "terraform" {
count = 4
ami = "ami-0dee22c13ea7a9a67"
instance_type = "t2.micro"
tags = {
Name = "terraform-instance-${count.index}"
}
}
In order to connect to your AWS account and terraform, you need the access keys and secret access keys exported to your machine.
export AWS_ACCESS_KEY_ID=<access key>
export AWS_SECRET_ACCESS_KEY=<secret access key>
Terraform init

Terraform plan
terraform plan
Terraform apply

You can use this de-referencing variable in between a string also like
# vi main.tf
tags = {
Name = "terraform-${count.index}-instance"
}
For-Each
Now if someone say to you that I will provide you a list of names and you have to use them to name the instances, then you can use for-each to get multiple de-referencing.
# vi main.tf
locals { # we have to declare it as a local variable
instance = toset(["Harshit","Aakib","Vijay","Rishabh"])
}
resource "aws_instance" "terraform" {
for_each = local.instance
ami = "ami-0dee22c13ea7a9a67"
instance_type = "t2.micro"
tags = {
Name = each.key
}
}
Why use toset in locals?
toset function, basically a list is collection of same data elements, so in list values can be replicate also and for_each works only on unique values that’s why we converted it in set.Terraform Locals
Terraform apply

Terraform Locals vs Variables
How does Terraform local differ from a Terraform variable?
The first difference can be pointed towards the scope. A Local is only accessible within the local module vs a Terraform variable, which can be scoped globally.
Another thing to note is that a local in Terraform doesn’t change its value once assigned. A variable value can be manipulated via expressions. This makes it easier to assign expression outputs to locals and use that throughout the code instead of using the expression itself at multiple places.
MAP IN LOCALS
Now if someone challenges us to make different name instances with different AMI using a single resource only. Then we must accept his challenge because we can do this using map data structure in locals.
# vi main.tf
locals { # we have to declare it as a local variable
instance = {"Harshit":"ami-0aebec83a182ea7ea","Aakib":"ami-0dee22c13ea7a9a67","Vijay":"ami-0aebec83a182ea7ea","Rishabh":"ami-0dee22c13ea7a9a67"}
}
resource "aws_instance" "terraform" {
for_each = local.instance
ami = each.value
instance_type = "t2.micro"
tags = {
Name = each.key
}
}
Terraform plan
terraform plan
Terraform apply
terraform apply --auto-approve
Depends_on
When a resource is dependent on other than we generally use this via depends_on= <resource-name>.
Using Terraform for_each to create subnets in AWS VPC
The two main drawbacks of using count are :
- Can’t be used to loop over inline blocks
- Difficult to remove entry from a list because it changes the index and those Terraform may want to destroy the resource because it has a different index
Below is an example of the variables used to create subnets within AWS VPCs and the main file with the for_each. The variables contain a map of subnets maps with cidr and az (availability zone) attributes. The for_each loop over the map of subnets maps to create the subnets.
variables.tf
variable "tag_name" {
default = "main-vpc"
}
variable "vpc-cidr" {
default = "10.0.0.0/16"
}
variable "basename" {
description = "Prefix used for all resources names"
default = "nbo"
}
#map of maps for create subnets
variable "prefix" {
type = map
default = {
sub-1 = {
az = "use2-az1"
cidr = "10.0.198.0/24"
}
sub-2 = {
az = "use2-az2"
cidr = "10.0.199.0/24"
}
sub-3 = {
az = "use2-az3"
cidr = "10.0.200.0/24"
}
}
}
main.tf
resource "aws_vpc" "main-vpc" {
cidr_block = var.vpc-cidr
tags = {
Name = var.tag_name
}
}
resource "aws_subnet" "main-subnet" {
for_each = var.prefix
availability_zone_id = each.value["az"]
cidr_block = each.value["cidr"]
vpc_id = aws_vpc.main-vpc.id
tags = {
Name = "${var.basename}-subnet-${each.key}"
}
}
You can find the output of the terraform plan/apply, the terraform.state and the others tf files in the below links.





