stackeval: Include component configurations in our static walks

This means both that the validate walk can now describe static problems in
the component's module tree, and that we'll catch such problems earlier
in the planning phase and thus avoid reporting them repeatedly in cases
where a component block uses for_each to declare multiple instances.

This includes a fix to a bug in StackConfig.Components, which was
incorrectly using the input variable declarations as the source for its
result, instead of the component declarations.
This commit is contained in:
Martin Atkins 2024-01-05 16:32:17 -08:00
parent a3cd4a11ce
commit a51c034cc3
3 changed files with 17 additions and 3 deletions

View file

@ -20,6 +20,7 @@ import (
"github.com/hashicorp/terraform/internal/promising"
"github.com/hashicorp/terraform/internal/stacks/stackaddrs"
"github.com/hashicorp/terraform/internal/stacks/stackconfig"
"github.com/hashicorp/terraform/internal/stacks/stackplan"
"github.com/hashicorp/terraform/internal/tfdiags"
"github.com/spf13/afero"
"github.com/zclconf/go-cty/cty"
@ -228,8 +229,7 @@ func (c *ComponentConfig) ExprReferenceValue(ctx context.Context, phase EvalPhas
return cty.DynamicVal
}
// Validate implements Validatable.
func (c *ComponentConfig) Validate(ctx context.Context) tfdiags.Diagnostics {
func (c *ComponentConfig) checkValid(ctx context.Context, phase EvalPhase) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
_, moreDiags := c.CheckModuleTree(ctx)
@ -238,6 +238,16 @@ func (c *ComponentConfig) Validate(ctx context.Context) tfdiags.Diagnostics {
return diags
}
// Validate implements Validatable.
func (c *ComponentConfig) Validate(ctx context.Context) tfdiags.Diagnostics {
return c.checkValid(ctx, ValidatePhase)
}
// PlanChanges implements Plannable.
func (c *ComponentConfig) PlanChanges(ctx context.Context) ([]stackplan.PlannedChange, tfdiags.Diagnostics) {
return nil, c.checkValid(ctx, PlanPhase)
}
func (c *ComponentConfig) tracingName() string {
return c.Addr().String()
}

View file

@ -303,7 +303,7 @@ func (s *StackConfig) Components(ctx context.Context) map[stackaddrs.Component]*
return nil
}
ret := make(map[stackaddrs.Component]*ComponentConfig, len(s.config.Stack.Components))
for name := range s.config.Stack.InputVariables {
for name := range s.config.Stack.Components {
addr := stackaddrs.Component{Name: name}
ret[addr] = s.Component(ctx, addr)
}

View file

@ -53,6 +53,10 @@ func walkStaticObjectsInStackConfig[Output any](
// TODO: All of the other static object types
for _, obj := range stackConfig.Components(ctx) {
visit(ctx, walk, obj)
}
for _, obj := range stackConfig.StackCalls(ctx) {
visit(ctx, walk, obj)
}