Skip to content

Commit

Permalink
improve Terraform scanning logging
Browse files Browse the repository at this point in the history
Signed-off-by: nikpivkin <[email protected]>
  • Loading branch information
nikpivkin committed Aug 13, 2024
1 parent 04de917 commit b80b51e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 16 deletions.
45 changes: 33 additions & 12 deletions pkg/iac/scanners/terraform/parser/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,39 @@ func (e *evaluator) exportOutputs() cty.Value {

func (e *evaluator) EvaluateAll(ctx context.Context) (terraform.Modules, map[string]fs.FS) {

fsKey := types.CreateFSKey(e.filesystem)
e.logger.Debug("Starting module evaluation...", log.String("path", e.modulePath))

fsMap := make(map[string]fs.FS)
fsMap[fsKey] = e.filesystem
fsKey := types.CreateFSKey(e.filesystem)
fsMap := map[string]fs.FS{
fsKey: e.filesystem,
}

e.logger.Debug("Starting module evaluation...")
e.evaluateSteps()

// expand out resources and modules via count, for-each and dynamic
// (not a typo, we do this twice so every order is processed)
e.blocks = e.expandBlocks(e.blocks)
e.blocks = e.expandBlocks(e.blocks)

e.logger.Debug("Starting submodule evaluation...")
submodules := e.evaluateSubmodules(ctx, fsMap)

e.logger.Debug("Starting post-submodules evaluation...")
e.evaluateSteps()

e.logger.Debug("Module evaluation complete.")
rootModule := terraform.NewModule(e.projectRootPath, e.modulePath, e.blocks, e.ignores)
return append(terraform.Modules{rootModule}, submodules...), fsMap
}

func (e *evaluator) evaluateSubmodules(ctx context.Context, fsMap map[string]fs.FS) terraform.Modules {
submodules := e.loadSubmodules(ctx)

if len(submodules) == 0 {
return nil
}

e.logger.Debug("Starting submodules evaluation...")

for i := 0; i < maxContextIterations; i++ {
changed := false
for _, sm := range submodules {
Expand All @@ -162,9 +179,7 @@ func (e *evaluator) EvaluateAll(ctx context.Context) (terraform.Modules, map[str
}

e.logger.Debug("Finished processing submodule(s).", log.Int("count", len(modules)))
e.logger.Debug("Module evaluation complete.")
rootModule := terraform.NewModule(e.projectRootPath, e.modulePath, e.blocks, e.ignores)
return append(terraform.Modules{rootModule}, modules...), fsMap
return modules
}

type submodule struct {
Expand Down Expand Up @@ -285,6 +300,7 @@ func isBlockSupportsForEachMetaArgument(block *terraform.Block) bool {
}

func (e *evaluator) expandBlockForEaches(blocks terraform.Blocks, isDynamic bool) terraform.Blocks {

var forEachFiltered terraform.Blocks

for _, block := range blocks {
Expand All @@ -299,6 +315,10 @@ func (e *evaluator) expandBlockForEaches(blocks terraform.Blocks, isDynamic bool
forEachVal := forEachAttr.Value()

if forEachVal.IsNull() || !forEachVal.IsKnown() || !forEachAttr.IsIterable() {
e.logger.Error(`Failed to expand block. Invalid "for-each" argument. Must be known and iterable.`,
log.String("block", block.FullName()),
log.String("value", forEachVal.GoString()),
)
continue
}

Expand All @@ -313,7 +333,7 @@ func (e *evaluator) expandBlockForEaches(blocks terraform.Blocks, isDynamic bool
idx, err := convert.Convert(key, cty.String)
if err != nil {
e.logger.Error(
`Invalid "for-each" argument: map key (or set value) is not a string`,
`Failed to expand block. Invalid "for-each" argument: map key (or set value) is not a string`,
log.String("block", block.FullName()),
log.String("key", key.GoString()),
log.String("value", val.GoString()),
Expand All @@ -330,7 +350,7 @@ func (e *evaluator) expandBlockForEaches(blocks terraform.Blocks, isDynamic bool
stringVal, err := convert.Convert(val, cty.String)
if err != nil {
e.logger.Error(
"Failed to convert for-each arg to string",
"Failed to expand block. Invalid 'for-each' argument: value is not a string",
log.String("block", block.FullName()),
log.String("key", idx.AsString()),
log.String("value", val.GoString()),
Expand Down Expand Up @@ -360,7 +380,8 @@ func (e *evaluator) expandBlockForEaches(blocks terraform.Blocks, isDynamic bool
ctx.Set(idx, refs[0].TypeLabel(), "key")
ctx.Set(val, refs[0].TypeLabel(), "value")
} else {
e.logger.Debug("Ignoring iterator attribute in dynamic block, expected one reference", log.Int("refs", len(refs)))
e.logger.Debug("Ignoring iterator attribute in dynamic block, expected one reference",
log.Int("refs", len(refs)))
}
}
}
Expand Down Expand Up @@ -424,7 +445,7 @@ func (e *evaluator) expandBlockCounts(blocks terraform.Blocks) terraform.Blocks
e.ctx.SetByDot(cty.TupleVal(clones), metadata.Reference())
}
e.logger.Debug(
"Expanded block '%s' into %d clones via 'count' attribute.",
"Expanded block into clones via 'count' attribute.",
log.String("block", block.FullName()),
log.Int("clones", len(clones)),
)
Expand Down
2 changes: 1 addition & 1 deletion pkg/iac/scanners/terraform/parser/load_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (e *evaluator) loadModule(ctx context.Context, b *terraform.Block) (*Module
}

if def, err := e.loadModuleFromTerraformCache(ctx, b, source); err == nil {
e.logger.Debug("found module in .terraform/modules", log.String("source", source))
e.logger.Debug("Using module from Terraform cache .terraform/modules", log.String("source", source))
return def, nil
}

Expand Down
15 changes: 13 additions & 2 deletions pkg/iac/scanners/terraform/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (p *Parser) ParseFS(ctx context.Context, dir string) error {
if p.stopOnHCLError {
return err
}
p.logger.Error("Error parsing", log.FilePath(path), log.Err(err))
p.logger.Error("Error parsing file", log.FilePath(path), log.Err(err))
continue
}
}
Expand All @@ -172,7 +172,7 @@ func (p *Parser) ParseFS(ctx context.Context, dir string) error {
var ErrNoFiles = errors.New("no files found")

func (p *Parser) Load(ctx context.Context) (*evaluator, error) {
p.logger.Debug("Evaluating module...")
p.logger.Debug("Loading module", log.String("module", p.moduleName))

if len(p.files) == 0 {
p.logger.Info("No files found, nothing to do.")
Expand All @@ -197,6 +197,17 @@ func (p *Parser) Load(ctx context.Context) (*evaluator, error) {
return nil, err
}
p.logger.Debug("Added input variables from tfvars", log.Int("count", len(inputVars)))

for _, varBlock := range blocks.OfType("variable") {
if varBlock.GetAttribute("default") == nil {
if _, ok := inputVars[varBlock.TypeLabel()]; !ok {
p.logger.Warn(
"Variable was not found in the environment or variable files. Evaluating may not work correctly.",
log.String("variable", varBlock.TypeLabel()),
)
}
}
}
}

modulesMetadata, metadataPath, err := loadModuleMetadata(p.moduleFS, p.projectRoot)
Expand Down
2 changes: 1 addition & 1 deletion pkg/iac/scanners/terraform/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (s *Scanner) ScanFS(ctx context.Context, target fs.FS, dir string) (scan.Re
sort.Strings(modulePaths)

if len(modulePaths) == 0 {
s.logger.Info("No modules found, skipping scanning")
s.logger.Info("No modules found, skipping directory", log.FilePath(dir))
return nil, nil
}

Expand Down

0 comments on commit b80b51e

Please sign in to comment.