Most engineers bring a programming mindset into Terraform and assume for behaves like a loop that creates infrastructure.
That assumption breaks your mental model.
A Terraform for expression does one thing: it reshapes data.
It takes an input collection, applies a transformation, and emits a new collection. The resource does not multiply. The state address does not change. Only the data flowing into the resource is different.
This distinction matters.
You can:
- Reformat lists before passing them into a resource
- Attach index-based structure to values
- Filter out invalid or empty entries inline
But you cannot create multiple resources with for. That boundary belongs to count and for_each.
There is also a hidden risk most people miss.
If your input is a set, Terraform does not guarantee order. If you assign meaning to positions after iterating a set, your logic becomes unstable without throwing an error.
The fix is simple but intentional: control ordering before assigning significance.
This lesson is not about syntax. It is about separating data transformation from infrastructure creation.
That separation is what keeps your Terraform predictable.

