Repository navigation
fix(parser): evaluate module outputs (#116) - #117
Merged
Merged
Conversation
Expressions reading module.<name>.<output> never resolved, so a count or for_each built from one dropped the block and an attribute set from one fell back to the catalog default. Module calls are now resolved before any resource is emitted: each call's instances are built, their own calls resolved recursively, and their output blocks evaluated in the module's scope. The outputs are added to the caller's scope as module.<name> (a tuple under count, an object keyed by each.key under for_each), and the caller's locals are resolved again, before the next call. Calls are ordered so one that reads module.X, directly or through a local, comes after X. Resources are emitted afterwards from the resolved tree, in the same order as before. Output blocks in Terraform JSON files are translated (value only).
This was referenced Oct 23, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #116.
Expressions reading
module.<name>.<output>never resolved. Nothing putmodulein the evaluation scope, and output blocks were never evaluated. So:countorfor_eachbuilt from a module output dropped the whole block;Change
outputblocks are evaluated in the module's scope.module.<name>: a tuple undercount, and an object keyed byeach.keyunderfor_each. The caller's locals are then resolved again before the next call.module.X(directly or through a local) comes afterX. A cycle is broken in source order, and the parse still finishes..tf.jsonfiles are now translated (onlyvalue).Verification
db.m7g.largefor both andq["a"]andq["b"]present.module_outputs_test.go: the Module outputs aren't evaluated: for_each over module.<name>.<output> drops the block #116 repro, outputs through locals with the consumer declared first,count/for_each/nested outputs, JSON outputs drivingcount, and a cycle. All of them fail onmainexcept the cycle test.go test ./...and golangci-lint v2.15.0 (Go 1.27.3) pass.BenchmarkParseLargeMonorepois about 5% slower (one extra locals pass per module).