Skip to content

Commit 81d9425

Browse files
authored
fix(misconf): ensure module source is known (#9404)
Signed-off-by: nikpivkin <[email protected]>
1 parent 1d646d6 commit 81d9425

File tree

4 files changed

+44
-16
lines changed

4 files changed

+44
-16
lines changed

pkg/iac/scanners/terraform/parser/load_module.go

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package parser
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"io/fs"
78
"path"
@@ -43,7 +44,9 @@ func (e *evaluator) loadModules(ctx context.Context) []*ModuleDefinition {
4344
}
4445
moduleDefinition, err := e.loadModule(ctx, moduleBlock)
4546
if err != nil {
46-
e.logger.Error("Failed to load module. Maybe try 'terraform init'?", log.Err(err))
47+
rng := moduleBlock.GetMetadata().Range()
48+
e.logger.Error("Failed to load module. Maybe try 'terraform init'?",
49+
log.String("loc", rng.String()), log.Err(err))
4750
continue
4851
}
4952

@@ -56,25 +59,18 @@ func (e *evaluator) loadModules(ctx context.Context) []*ModuleDefinition {
5659

5760
// takes in a module "x" {} block and loads resources etc. into e.moduleBlocks - additionally returns variables to add to ["module.x.*"] variables
5861
func (e *evaluator) loadModule(ctx context.Context, b *terraform.Block) (*ModuleDefinition, error) {
59-
60-
metadata := b.GetMetadata()
61-
6262
if b.Label() == "" {
63-
return nil, fmt.Errorf("module without label at %s", metadata.Range())
63+
return nil, errors.New("module without label")
6464
}
6565

66-
var source string
67-
attrs := b.Attributes()
68-
for _, attr := range attrs {
69-
if attr.Name() == "source" {
70-
sourceVal := attr.Value()
71-
if sourceVal.Type() == cty.String {
72-
source = sourceVal.AsString()
73-
}
74-
}
66+
sourceVal := b.GetAttribute("source").Value()
67+
if !sourceVal.IsKnown() || sourceVal.Type() != cty.String {
68+
return nil, errors.New("source is not a string")
7569
}
70+
71+
source := sourceVal.AsString()
7672
if source == "" {
77-
return nil, fmt.Errorf("could not read module source attribute at %s", metadata.Range().String())
73+
return nil, errors.New("source is empty")
7874
}
7975

8076
if e.moduleMetadata != nil {

pkg/iac/scanners/terraform/parser/modules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func buildGraph(blocks terraform.Blocks, paths []string) modulesGraph {
4848

4949
for _, block := range moduleBlocks {
5050
sourceVal := block.GetAttribute("source").Value()
51-
if sourceVal.Type() != cty.String {
51+
if !sourceVal.IsKnown() || sourceVal.Type() != cty.String {
5252
continue
5353
}
5454

pkg/iac/scanners/terraform/parser/modules_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ module "this" {
5757
"code/infra2",
5858
},
5959
},
60+
{
61+
name: "unknown module source",
62+
files: map[string]string{
63+
"main.tf": `module "test" {
64+
source = "${path.module}/modules/foo"
65+
}`,
66+
},
67+
expected: []string{"."},
68+
},
6069
}
6170

6271
for _, tt := range tests {

pkg/iac/scanners/terraform/parser/parser_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2854,3 +2854,26 @@ locals {
28542854
attr := bucket.GetAttribute("test")
28552855
require.Equal(t, "some_value", attr.Value().AsString())
28562856
}
2857+
2858+
func Test_UnknownModuleSource(t *testing.T) {
2859+
files := map[string]string{
2860+
`main.tf`: `
2861+
module "test" {
2862+
source = "${foo}/modules/foo"
2863+
}
2864+
`,
2865+
}
2866+
2867+
fsys := testutil.CreateFS(t, files)
2868+
parser := New(fsys, "",
2869+
OptionWithSkipCachedModules(true),
2870+
OptionStopOnHCLError(true),
2871+
)
2872+
err := parser.ParseFS(t.Context(), ".")
2873+
require.NoError(t, err)
2874+
2875+
modules, err := parser.EvaluateAll(t.Context())
2876+
require.NoError(t, err)
2877+
2878+
require.Len(t, modules, 1)
2879+
}

0 commit comments

Comments
 (0)