Skip to main content
In this lesson we cover Terraform’s for_each meta-argument — the recommended way to create multiple resources when instance identity and lifecycle stability matter. Unlike count, for_each ties each resource instance to a meaningful key, which prevents index-shifting and makes changes safer and more predictable for production workloads.
The image has a gradient blue background with the text "Using for_each" in white in the center.
Why use for_each? When resources are keyed by meaningful identifiers (names, subnet IDs, DNS names, etc.), Terraform can track each resource independently. This prevents accidental destruction and recreation caused by reordering or changing collections that are tracked only by numeric indexes.
The image has a blue gradient background with the text "Using for_each" in the center. In the bottom left corner, it says "Copyright KodeKloud".
Example: create a resource group for every element in a set
Key notes about this example:
  • variable.resource_groups is declared as set(string): a collection of unique values without a guaranteed order.
  • for_each = var.resource_groups creates one resource instance per element in the set.
  • When iterating a set, both each.key and each.value refer to the element value (e.g., "rg-dev" and "rg-prod"). When iterating a map, each.key is the map key and each.value is the map value.
Because for_each uses meaningful keys rather than numeric indexes, Terraform state does not shift when you add or remove other items. This makes for_each far safer than count in many production scenarios.
Prefer for_each when each resource has a meaningful identifier (name, subnet ID, DNS name, etc.). Use count only for N identical resources where individual identity or lifecycle does not matter.
Why index-based count is brittle With count, Terraform identifies resources by their numeric index (0, 1, 2, …). Reordering or removing elements can change those indexes and cause Terraform to destroy and recreate resources unnecessarily. count-style example (index-based):
A truncated plan showing index-based change:
Convert the same example to for_each to avoid index shifting
Notes on referencing for_each results:
  • A resource using for_each becomes a map keyed by the iteration key. Reference an instance with azurerm_resource_group.rg["0"].name.
  • Avoid mixing index-based references (e.g., rg[0]) with map-style lookups from for_each. Use map-style lookups consistently.
Quick comparison: for_each vs count Typical local workflow
Example apply output (abridged):
Targeting and destroying a single for_each instance
  • Using terraform destroy --target 'azurerm_resource_group.rg["0"]' or terraform apply -target=... is possible but generally discouraged for routine operations. Terraform will warn you when targeting because the plan may not represent all configuration changes.
Example warning when using -target (abridged):
Avoid relying on -target for normal workflows. Targeting can produce incomplete or unsafe plans when resources have dependencies, and may cause unintended changes.
Recommended pattern to remove an instance managed by for_each
  1. Update the collection used by for_each to remove the key you want to delete.
  2. Run terraform plan and terraform apply. Terraform will plan and destroy only the resource whose key was removed and leave other keyed instances intact.
Example: remove the instance with key "1" Before:
After (removed "1"):
Then:
Resulting plan shows only the removed key scheduled for destruction:
Summary and best practices
  • Use for_each when instances have meaningful identities (names, subnet IDs, DNS records, etc.). It maps instances to stable keys and prevents index-driven recreation.
  • Use count only when you truly need N indistinguishable, ordinal resources.
  • Reference for_each instances with resource.name["key"], and avoid mixing indexing styles.
  • To remove a single instance, remove its key from the for_each collection and apply the change. Avoid -target unless you fully understand the dependency implications.
Links and references

Watch Video