Terraform Referencing resources created in for_each in another resource
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
When a Terraform resource uses for_each, the result is not one resource object anymore. Terraform turns that resource into a map of resource instances keyed by the for_each keys. Most confusion comes from forgetting that shape change and then trying to reference the result as though it were a single object or a list.
Once you keep the map model in mind, the rest becomes much easier. You either reference one specific instance by key, iterate over the map in another for_each, or build a derived map of the attributes you need.
Understand the Shape of a for_each Resource
Suppose you create multiple subnets from a map:
Because aws_subnet.app uses for_each, Terraform treats aws_subnet.app as a map of objects. That means you reference a specific instance by key:
This is the most important rule in the whole topic. for_each gives you a keyed map, not a numeric index.
Reference a Specific Instance in Another Resource
If another resource needs exactly one of those subnets, use the matching key directly.
This works well when the dependency is one-to-one and you know which instance key you want.
The common mistake is writing something list-like such as aws_subnet.app[0].id. That fails because for_each instances are keyed by strings or set members, not numeric positions.
Chain for_each Into Another Resource
A very common pattern is creating a second resource for every instance of the first one. Terraform supports that directly because a for_each resource can feed another for_each.
Here, each.key is the subnet key and each.value is the full subnet object. This “chain pattern” is often the cleanest answer because it preserves the relationship between the two resource sets.
If you need an attribute from the upstream resource, use each.value:
Build a Derived Map When You Need Only Certain Attributes
Sometimes a downstream resource or output only needs selected attributes. A for expression is useful there.
This makes the data shape explicit and often improves readability, especially in modules where the output should stay small and predictable.
Be Careful With Sets Versus Maps
for_each accepts maps and sets of strings. If you use a set, each.key and each.value are effectively the same string. If you need named attributes, maps are usually clearer.
Sets are fine for simple one-value cases. Maps are better when you want stable named instances with associated configuration.
Common Pitfalls
The biggest mistake is treating a for_each resource as one object or as an indexed list. It is a map, so references must use keys.
Another issue is generating unstable keys. If the keys change, Terraform sees different instances and may destroy and recreate resources.
A third problem is using a list when the design really needs a map. Lists encourage index thinking, while for_each works best with stable keys that express meaning.
Summary
- A resource created with
for_eachbecomes a map of instances. - Reference one instance with a key, such as
resource.name["key"].id. - Use one
for_eachresource directly as thefor_eachof another for one-to-one chaining. - Build derived maps with
forexpressions when you need only selected attributes. - Prefer stable, meaningful keys so Terraform can track instances predictably.
Related reading
- Test Container test cases are failing due to Could not find a valid Docker environment
- Thanos-Query/Query-Frontend does not show any metrics
- The ClusterRoleBinding kubernetes-dashboard is invalid roleRef Invalid value when deploying Web UI
- The dns-controller Kubernetes deployment has not updated the Kubernetes cluster's - AWS
- The iOS deployment target ''IPHONEOS_DEPLOYMENT_TARGET'' is set to 8.0, in Flutter How can I change the minimum IOS Deploying Target
- The iOS Simulator deployment targets is set to 7.0, but the range of supported deployment target version for this platform is 8.0 to 12.1
- The source was not found, but some or all event logs could not be searched
- The target group does not have an associated load balancer

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.