linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/how/tf-count-vs-for-each

how/resources

count vs for_each: why deleting one user breaks the rest

Two ways to create N identical resources. One indexes by number, the other by key. Deleting the middle of the array produces completely different plans.

count and for_each are two ways to create several instances of one resource. From the outside they look similar:

hcl
# count
resource "aws_iam_user" "users" {
  count = length(var.users)
  name  = var.users[count.index]
}
# for_each
resource "aws_iam_user" "users" {
  for_each = toset(var.users)
  name     = each.key
}

The difference is hidden in state. count writes resources under indexes [0], [1], [2]. for_each writes them under keys ["alice"], ["bob"], ["carol"]. That changes everything when you delete an element from the middle.

Hit ▶ and watch how the same var.users with a deleted middle breaks the count version and leaves for_each untouched.

step 1/5·00 · one set of users, two ways
COUNT = LENGTH(VAR.USERS)индексы [0], [1], [2]FOR_EACH = TOSET(VAR.USERS)ключи ["alice"], ["bob"]…variable "users" { default = ["alice","bob","carol"]}resource "aws_iam_user" "users" { count = length(var.users) name = var.users[count.index]}variable "users" { default = ["alice","bob","carol"]}resource "aws_iam_user" "users" { for_each = toset(var.users) name = each.key}один и тот же набор юзеров - двумя способами

§ steps

  1. On the left, a standard count with an index into the array. On the right, for_each over toset(...), because for_each wants a collection with unique keys.

    For the goal of "create three IAM users" both versions are equivalent. The difference shows up later, when we try to change something.

recap

What to remember:

  • count indexes by position in the array. Delete an element from the middle and every element after it shifts one position left. To Terraform that is a destroy + create for each shifted index.
  • for_each indexes by key. Delete the key "bob" and Terraform sees exactly one change: destroy users["bob"]. The rest are untouched.
  • At the AWS level this means: count recreates half of your IAM users, and those users may have attached access keys, policies, and MFA tokens. Recreation means losing those attachments.
  • for_each requires the values to be unique (which is why you usually use toset(...)) and known at plan time. If a key is a uuid() or the result of aws_instance.x.id for a resource that does not exist yet, Terraform fails with The "for_each" map includes keys derived from resource attributes.
  • Migrating from count to for_each without destroy/create is exactly the case where you need a moved block: moved { from = aws_iam_user.users[1] to = aws_iam_user.users["bob"] }. See tf-moved-block.
  • Rule: use for_each always, except when you genuinely need numeric indexes (an array without natural unique keys).

Next: tf-resource-lifecycle on controlling resource behavior at the HCL level.

§ dig into the knowledge base

  • tf-count-for-eachcount and for_each in detail
  • tf-moved-blockmoved block: migration between forms
  • tf-state-manipulationstate mv for the same migration
  • tf-referencesReferences to instances: [0] vs ["key"]

§ try it hands-on

  • ›tf-beginner-08-count- count in practice
  • ›tf-intermediate-03-module-for-each- for_each on modules
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies