Terraform Count vs For_Each

Learn when to use count vs for_each with Terraform

Terraform offers several ways to manage multiple similar resources, and two of the most common are the for_each and count meta-arguments. Choosing the right one depends on your specific use case.

Count Meta-Argument

The count meta-argument is a straightforward way to create a fixed number of identical resources. It's best used when you know exactly how many instances you need and they don't require unique identifiers beyond their index.

When to use count:

  • You need to create a specific, predetermined number of resources.
  • The resources are functionally identical, with no need for unique names or properties other than their index.
  • You want to manage the resources as a simple, indexed list.

Example: Creating three identical virtual machines. The instances will be named with a simple index suffix like vm-0, vm-1, and vm-2.

resource "aws_instance" "example" {
  count         = 3
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "vm-${count.index}"
  }
}

For_each Meta-Argument

The for_each meta-argument is a powerful tool for creating resources based on a map or set of strings. It's the ideal choice when you need each resource to have a unique identifier and you want to manage them as distinct entities rather than a simple list.

When to use for_each:

  • You need to create resources with unique, user-defined names.
  • You're using a map or a set to define resource properties.
  • The number of resources is dynamic and based on the input data.
  • You need to reference specific resources by their key, not by a numerical index.

Example: Creating virtual machines with unique names and varying instance types, defined by a map.

locals {
  vms = {
    "web" = {
      instance_type = "t2.micro"
    },
    "db" = {
      instance_type = "t2.medium"
    },
    "app" = {
      instance_type = "t2.large"
    }
  }
}

resource "aws_instance" "example" {
  for_each      = local.vms
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = each.value.instance_type
  tags = {
    Name = "vm-${each.key}"
  }
}

Key Differences and Considerations

Featurecountfor_each
Input TypeInteger (number of resources)Map or set of strings
Resource NamingIndexed (e.g., resource_name[0])Key-based (e.g., resource_name["key"])
Use CaseFixed number of identical resourcesDynamic number of unique resources
Deleting ResourcesShifting indices can cause a cascade of changesDeleting a key removes only that specific resource

Recommendation

Unless you have a strong reason to use count, it's generally recommended to use for_each for managing multiple resources. The key-based lookup of for_each makes it much safer and more predictable when resources are added or removed, preventing unintended changes to other resources. Count is best reserved for simple, truly identical resources where an index is sufficient.