This is an ancillary document to the [Static Evaluation RFC](20240513-static-evaluation.md) and is not planned on being implemented. It serves to document the reasoning behind why we are deciding to defer implementation of this complex functionality. For now, we have decided to implement a limited version of this that allows provider aliases *only* to be specified via for_each/count.
This document should be used as a reference for anyone considering implementing this in the future. It is not designed as a comprehensive guide, but instead as documenting the previous exploration of this concept during the prototyping phase of the Static Evaluation RFC.
# Static Module Expansion
Modules may be expanded using for_each and count. This poses a problem for the static evaluation step.
Each instance of "mod" will have a different source. This is a complex situation that must have intense validation, inputs and outputs must be identical between the two modules.
The example is a bit contrived, but is a simpler representation of why it's difficult to have different module sources for different instances down a configuration tree.
If we want to allow this, modules which have static for_each and count expressions must be expanded at the config layer. This must happen before the graph building, transformers, and walking.
This document assumes you have read the [Static Evaluation RFC](20240513-static-evaluation.md) and understand the concepts in there.
## Current structure and paths
Over half of OpenTofu does not understand module/resource instances. They have a simplified view of the world that is called "pre-expansion".
Relevant components for this document:
Pre-expansion:
* Module structure in configs package
* ModuleCalls structure in configs package
* Config tree in configs package
* Module cache file/filetree
* Graph structure and transformers in tofu package (mixed)
* EvaluationContext (mixed)
Post-expansion
* Graph structure and transformers in tofu package (mixed)
To implement a fully fledged static evaluator which supports for_each and count on modules/providers, the concept of module instances must be brought to all components in the previous section.
One approach is to remove the concept of a "non-instanced" module path and simply deleted addrs.Module entirely and changed all references to addrs.ModuleInstance (among a number of other changes). This is a incredibly complex change with many ramifications.
addrs.Module is simply a []string, while addrs.ModuleInstance is a pair of {string, key} where key is: