Understanding Terraform Meta-Arguments: Count and For_Each

Kanav GatheKanav Gathe
4 min read

Introduction

When working with Infrastructure as Code (IaC) using Terraform, you often need to create multiple instances of the same resource. Instead of copying and pasting the same resource block multiple times, Terraform provides powerful meta-arguments like count and for_each that help you manage multiple similar resources efficiently. In this blog post, we'll dive deep into these meta-arguments and explore their practical applications.

What are Meta-Arguments?

Meta-arguments are special arguments in Terraform that can be used within any resource block to control how Terraform manages that resource. They're called "meta" arguments because they affect Terraform's behavior rather than configuring the resource itself.

The Count Meta-Argument

Understanding Count

The count meta-argument is the simplest way to create multiple instances of a resource. It accepts a whole number and creates that many instances of the resource.

Example of Count

resource "aws_instance" "server" {
  count         = 3
  ami           = "ami-08c40ec9ead489470"
  instance_type = "t2.micro"

  tags = {
    Name = "Server-${count.index + 1}"
    Type = "Count Example"
  }
}

In this example:

  • count = 3 creates three identical EC2 instances

  • count.index is used to give each instance a unique name (Server-1, Server-2, Server-3)

  • All other attributes remain identical across instances

When to Use Count

  • Creating multiple identical resources

  • Simple scaling scenarios

  • When you need numeric indexing

  • When the number of resources is determined by a variable

The For_Each Meta-Argument

Understanding For_Each

The for_each meta-argument is more sophisticated than count. It can iterate over either:

  • A map of key-value pairs

  • A set of strings

Example 1: For_Each with Set

locals {
  instance_types = toset([
    "t2.micro",
    "t2.small",
    "t3.micro"
  ])
}

resource "aws_instance" "server" {
  for_each      = local.instance_types
  ami           = "ami-08c40ec9ead489470"
  instance_type = each.key

  tags = {
    Name = "Server-${each.key}"
    Type = "ForEach Set Example"
  }
}

Example 2: For_Each with Map

locals {
  server_configs = {
    "web" = {
      instance_type = "t2.micro"
      environment   = "prod"
    }
    "app" = {
      instance_type = "t2.small"
      environment   = "staging"
    }
    "db" = {
      instance_type = "t3.micro"
      environment   = "dev"
    }
  }
}

resource "aws_instance" "server" {
  for_each      = local.server_configs
  ami           = "ami-08c40ec9ead489470"
  instance_type = each.value.instance_type

  tags = {
    Name        = "Server-${each.key}"
    Environment = each.value.environment
  }
}

When to Use For_Each

  • When resources need different configurations

  • When working with key-value pairs

  • When you need string-based keys instead of numeric indices

  • When you want more stable resource addressing

Count vs For_Each: Making the Right Choice

Advantages of Count

  1. Simpler syntax

  2. Good for numeric iterations

  3. Works well with simple, identical resources

  4. Easy to scale with variables

Advantages of For_Each

  1. More flexible configuration options

  2. Better for managing distinct resources

  3. More stable when adding/removing resources

  4. Clearer resource addressing

Practical Guidelines

  • Use count when:

    • All instances are identical except for their index

    • You need simple numeric iteration

    • The number of resources might change frequently

  • Use for_each when:

    • Resources need distinct configurations

    • You need named instances instead of numbered ones

    • You're working with maps of configuration data

    • You need more stable resource addressing

Real-World Implementation

Let's look at the output of our implementation:

  1. Initialization: Run terraform init to set up the provider

  2. Planning: terraform plan shows what will be created

  3. Application: terraform apply creates the resources

  4. Verification: Check AWS Console to see:

    • Count-based instances (Server-1, Server-2, Server-3)

    • ForEach set instances (different instance types)

    • ForEach map instances (web, app, db servers)

Best Practices

  1. Use meaningful names in tags and identifiers

  2. Keep resource configurations DRY (Don't Repeat Yourself)

  3. Use locals for complex data structures

  4. Document your code with clear comments

  5. Always use version constraints for providers

  6. Test with terraform plan before applying changes

Conclusion

Meta-arguments in Terraform are powerful tools for managing multiple resources efficiently. While count offers simplicity for identical resources, for_each provides flexibility for more complex scenarios. Understanding when to use each one will help you write more maintainable and scalable infrastructure code.

Remember to always clean up your resources with terraform destroy when you're done experimenting to avoid unnecessary charges!

0
Subscribe to my newsletter

Read articles from Kanav Gathe directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kanav Gathe
Kanav Gathe