Skip to content

/compare/terraform/count-vs-for-each

Terraform count vs for_each: which one to use

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · Terraform v1.16.6updated 2026-10-20
tool
Terraform
compares
count vs for_each

count = N creates N instances addressed by position: res[0], res[1]. for_each takes a map or a set of strings and addresses instances by key: res["web"]. Use for_each whenever the instances have their own identity, and keep count for identical copies or for an on/off switch (count = var.enabled ? 1 : 0).

Same list, two addresses

bash
cat > main.tf <<'EOF'
variable "names" {
  type    = list(string)
  default = ["web", "api", "worker"]
}
resource "terraform_data" "by_count" {
  count = length(var.names)
  input = var.names[count.index]
}
resource "terraform_data" "by_each" {
  for_each = toset(var.names)
  input    = each.key
}
EOF
terraform init -input=false -no-color >/dev/null
terraform plan -no-color -input=false | grep 'will be created'

Output

  # terraform_data.by_count[0] will be created
  # terraform_data.by_count[1] will be created
  # terraform_data.by_count[2] will be created
  # terraform_data.by_each["api"] will be created
  # terraform_data.by_each["web"] will be created
  # terraform_data.by_each["worker"] will be created

Criterion by criterion

Criterioncountfor_each
Addressres[0], res[1], …res["web"], res["api"], …
Remove the first item of the listevery later instance shifts index: Terraform updates or replaces themonly res["web"] is destroyed
Inputa whole numbera map, or a set of strings (toset(list))
Inside the blockcount.indexeach.key, each.value
Values known at plan timethe number must be knownthe keys must be known
Good forN identical copies, or 0/1 conditional resourcesnamed things: buckets, users, subnets

Switching from count to for_each

Changing the meta-argument changes every address, so without help Terraform would destroy and recreate everything. Add moved blocks to keep the existing objects:

hcl
moved {
  from = terraform_data.by_count[0]
  to   = terraform_data.by_each["web"]
}

Sources