Two meta-arguments create multiple instances from one resource block. They look interchangeable and are not, and choosing wrongly is one of the most common ways to destroy infrastructure by accident.\n\nThe difference is how instances are identified.\n\n| | count | for_each |\n|---|---|---|\n| Takes | A number | A map or set of strings |\n| Identifies instances by | Position ([0], [1]) | Key ([\"web\"], [\"api\"]) |\n| Iterator | count.index | each.key, each.value |\n| Removing a middle item | Shifts everything after it | Affects only that item |\n\n## count\n\nhcl\nresource \"aws_instance\" \"worker\" {\n count = 3\n ami = data.aws_ami.al2023.id\n instance_type = \"t3.micro\"\n\n tags = { Name = \"worker-${count.index}\" }\n}\n\n\nThree instances, addressed aws_instance.worker[0] through [2].\n\nReference them individually by index, or all at once with a splat:\n\nhcl\naws_instance.worker[0].id\naws_instance.worker[*].id # a list of all IDs\n\n\n## The problem with count\n\nThis is the part that matters, and it is worth understanding precisely.\n\nhcl\nvariable \"buckets\" {\n default = [\"logs\", \"artifacts\", \"backups\", \"reports\"]\n}\n\nresource \"aws_s3_bucket\" \"this\" {\n count = length(var.buckets)\n bucket = var.buckets[count.index]\n}\n\n\nState now holds:\n\n\n[0] = logs\n[1] = artifacts\n[2] = backups\n[3] = reports\n\n\nRemove \"artifacts\" from the middle of that list and everything shifts down:\n\n\n[0] = logs unchanged\n[1] = backups was artifacts → destroy and recreate\n[2] = reports was backups → destroy and recreate\n[3] = (gone) was reports → destroy\n\n\nOne removal, three resources destroyed. Terraform is behaving correctly, index [1] genuinely changed from artifacts to backups, but the result is that deleting one bucket destroys two unrelated ones.\n\nOn stateless resources this is wasteful. On databases, volumes, or anything holding data, it is an outage.\n\n## for_each\n\nfor_each keys instances by a stable string instead:\n\n```hcl\nresource "aws_s3_bucket" "this" {\n for_each = toset(["logs", "artifacts", "backups", "reports\
Learn how the Terraform count meta-argument works: use count.index, build conditional resources, reference counted resources and know when count fits.
Learn how Terraform for_each works with sets, maps and objects, how each.key and each.value are used, how to reference instances and when it beats count.
Learn Terraform expressions: types, references, conditionals, for expressions, key function categories, try and can, and testing in terraform console.