Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Resources  ›  Lesson

Many Copies with count and for_each

Meta Arguments 12 minThe meta-arguments count and for_each make one resource block produce several objects, addressed by number with count.index or by key with each.key, and for_each keeps objects stable when items are added or removed.

Many Copies with count and for_each

Crumb now wants separate buckets for images, menus and logs. Writing three almost identical blocks works, but it is repetitive and easy to get out of step. Terraform's meta-arguments — arguments every resource accepts, whatever its provider — include two for making many objects from one block.

The rule

count for identical copies by number; for_each for named items by key.

count takes a whole number and makes that many objects. Inside the block, count.index is the position, starting at 0.

resource "aws_instance" "web" {
  count         = 2
  ami           = "ami-0123456789abcdef0"
  instance_type = "t3.micro"

  tags = {
    Name = "crumb-web-${count.index}"
  }
}

Addresses: aws_instance.web[0], aws_instance.web[1]. All IDs at once: aws_instance.web[*].id. A common trick is count = var.enable_web ? 1 : 0 to switch a resource on or off.

for_each takes a map, or a set of strings, and makes one object per key. Inside the block, each.key and each.value describe the current item.

resource "aws_s3_bucket" "b" {
  for_each = toset(["images", "menus", "logs"])
  bucket   = "crumb-prod-${each.key}"
}

Addresses: aws_s3_bucket.b["images"], aws_s3_bucket.b["menus"], aws_s3_bucket.b["logs"]. For a set, each.value equals each.key; for a map, each.value is the map's value.

The objects are still separate in state. Elsewhere you can refer to one of them, such as aws_s3_bucket.b["logs"].arn, and a plan lists each on its own line, so you always see exactly which copy is changing.

A block may use count or for_each, never both. And the number or keys must be known when planning, not something only created during apply.

The shortcut

Ask "If I remove one from the middle, should the others notice?" They never should, which is why items with names belong in for_each. With count, positions shift.

Removing menus from Crumb's bucketsStep 1 of 4
  1. With count over a list

    Buckets are [0] images, [1] menus, [2] logs.

Use count when the copies are truly interchangeable, or for the on/off switch.

Drills

Answer fast — trust the rule.

quick drill

With count = 3, what is count.index for the last object?

quick drill

What is the address of the logs bucket in the for_each example?

quick drill

Which value can for_each accept directly?

quick drill

Which line creates a resource only when var.enable_web is true?

Remember

  • count: copies by number, count.index from 0; for_each: items by key, each.key and each.value.
  • Shortcut: if removing one should not disturb the others, use for_each.
  • Trap: never both on one block, and count indexes shift when a middle item goes.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

Explaincount or for_each?

Crumb needs three buckets: images, menus and logs. Explain whether to use count or for_each, write the key line of the block, give the address of the menus bucket, and describe what goes wrong with the other choice when 'menus' is later removed.