for_each meta-argument to create multiple, uniquely configured resources from a single resource block. for_each is a more flexible alternative to count when you need per-resource uniqueness rather than many identical instances.
Why use for_each (versus count)
for_eachiterates over a map or set, allowing unique configuration per instance.- Each instance receives a stable key (the map key or set element) instead of an index. This stability reduces accidental recreation of unrelated resources when items are added or removed.
- Use
for_eachwhen resources need different names, sizes, tags, networks, or other unique attributes. - Inside the resource block you can reference
each.keyandeach.valueto access the current item.
var.vms contains three key/value pairs, Terraform creates three VMs: vm1, vm2, and vm3, each with its configured size.
Referencing resources created with for_each
- Address an individual instance by its key in square brackets:
azurerm_virtual_machine.example["vm1"]azurerm_virtual_machine.example["vm2"]azurerm_virtual_machine.example["vm3"]
- Use these keyed references when wiring resources together (for example, passing an instance ID or IP to another resource).
each.key and each.value inside the block
each.keyis the map key (here, the VM name).each.valueis the map value (here, the VM size).- You can reference
each.key/each.valuemultiple times to configure name, tags, hostnames, and more. - Combine them in interpolations. For example, to add a suffix to the computer name:
- Prefer
for_eachwhen instances require distinct attributes or when you want stable addressing that won’t shift as you add or remove items. countis still useful when creating many identical resources where uniqueness is not needed.- Map values can be primitive (strings, numbers) or nested objects to carry richer per-resource configuration (regions, tags, disk sizes, network IDs, etc.).
for_each vs count
| Feature | for_each | count |
|---|---|---|
| Iterates over | map or set | integer range |
| Stable addressing | Yes — keyed by map/set element (each.key) | No — indexed by position (0..n-1) |
| Best for | Resources with unique attributes | Repeated identical resources |
| Example | for_each = var.vms | count = var.instance_count |
Prefer
for_each when your instances have unique attributes or when you want stable instance addressing that won’t shift as items are added or removed.When converting existing resources from
count to for_each (or vice versa), resource addresses change. This can cause Terraform to plan to recreate resources unless you import or manipulate state appropriately. Always review the plan and consider state migration steps.for_each meta-argument and how it compares to count. Use for_each to keep your configuration DRY while enabling per-resource uniqueness and stable addressing.