-
Notifications
You must be signed in to change notification settings - Fork 2.5k
test(terraform): test to demonstrate 'count' meta argument incorrectl… #8479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@nikpivkin and @simar7, what are your thoughts on this bug? The unit test is a good example and self description. It fails on the latest The test only passes because I added in I don't have a good solution for a more robust fix. |
Hi @Emyrk ! Thanks. I'll look into it. |
@nikpivkin any updates on your thoughts? |
29a795b
to
6b58370
Compare
// A pointer for this module is needed up front to correctly set the module parent hierarchy. | ||
// The actual instance is created at the end, when all terraform blocks | ||
// are evaluated. | ||
rootModule := new(terraform.Module) | ||
|
||
submodules := e.evaluateSubmodules(ctx, rootModule, fsMap) | ||
|
||
e.logger.Debug("Starting post-submodules evaluation...") | ||
e.evaluateSteps() | ||
|
||
e.logger.Debug("Module evaluation complete.") | ||
// terraform.NewModule must be called at the end, as `e.blocks` can be | ||
// changed up until the last moment. | ||
*rootModule = *terraform.NewModule(e.projectRootPath, e.modulePath, e.blocks, e.ignores) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels really unfortunate 😢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR currently only solves this for count
, but the same problem exists for other expansion block types. If this solution is satisfactory, I can write some tests for the other meta arguments.
Updated to solve for_each
as well
// Always attempt to expand any blocks that might now be expandable | ||
// due to new context being set. | ||
e.blocks = e.expandBlocks(e.blocks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the biggest change. It allows expandBlocks
to occur in evaluateSteps
.
From my understanding of expandBlocks
this should be a safe operation. Is there a reason it is currently called outside this context? @nikpivkin ?
Do not expand unknown `count` blocks. Run `expandBlocks` in eval to allow submodule returns to affect the `count` when using module outputs.
The depth of submodule evalutation is still limited
Module counts are incorrectly being handled
80e01d1
to
6eb6063
Compare
func TestBlockCountModules(t *testing.T) { | ||
t.Skip( | ||
"This test is currently failing. " + | ||
"The count passed to `module bar` is not being set correctly. " + | ||
"The count value is sourced from the output of `module foo`. " + | ||
"Submodules cannot be dependent on the output of other submodules right now. ", | ||
) | ||
// `count` meta attributes are incorrectly handled when referencing | ||
// a module output. | ||
files := map[string]string{ | ||
"main.tf": ` | ||
module "foo" { | ||
source = "./modules/foo" | ||
} | ||
module "bar" { | ||
source = "./modules/foo" | ||
count = module.foo.staticZero | ||
} | ||
`, | ||
"modules/foo/main.tf": ` | ||
output "staticZero" { | ||
value = 0 | ||
} | ||
`, | ||
} | ||
|
||
modules := parse(t, files) | ||
require.Len(t, modules, 2) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does evaluating sub-modules also need to occur in the inner loop? Defering them if their count
/for_each
is unknown?
@nikpivkin I updated this PR against the latest main. It solves an issue using It does not solve submodules dependent on each other 😢. |
@nikpivkin and @simar7 sorry to keep pinging you on this. Just want to make sure it does not slip through the cracks |
Description
count
&for_each
meta argument is incorrectly handled when referencing a submodule's output. The expansion arguments only work when referencing within the same scope.This is being caused because
expandBlockCounts
defaults to acount = 1
for unknown values.ExpandingBlocks happens before submodule evaluation:
https://github.com/aquasecurity/trivy/blob/main/pkg/iac/scanners/terraform/parser/evaluator.go#L139-L142
So expanded blocks cannot reference submodule exports. This is inc 8000 onsistent with
terraform plan/apply
which renders 0data
blocks in this unit test.The solution presented allows
expandBlocks
to be called duringevaluateSteps
, which occurs again after submodules are expanded.There is still an issue if the
count
/for_each
argument is used in a module block, meaning a submodule depends on another module output. Since submodule evaluation will not happen again. See the testTestBlockCountModules
. It is skipped for now.Checklist