From b4b42209e3d2752a6c06318bca7e2a6d9abc68dc Mon Sep 17 00:00:00 2001 From: nikpivkin Date: Fri, 26 Jul 2024 13:50:31 +0700 Subject: [PATCH] feat(misconf): iterator argument support for dynamic blocks Signed-off-by: nikpivkin --- .../scanners/terraform/parser/evaluator.go | 12 +++++++ .../scanners/terraform/parser/parser_test.go | 36 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/pkg/iac/scanners/terraform/parser/evaluator.go b/pkg/iac/scanners/terraform/parser/evaluator.go index bf3e4f4ffc13..0e26103e8c96 100644 --- a/pkg/iac/scanners/terraform/parser/evaluator.go +++ b/pkg/iac/scanners/terraform/parser/evaluator.go @@ -340,6 +340,18 @@ func (e *evaluator) expandBlockForEaches(blocks terraform.Blocks, isDynamic bool ctx.Set(idx, block.TypeLabel(), "key") ctx.Set(val, block.TypeLabel(), "value") + if isDynamic { + if iterAttr := block.GetAttribute("iterator"); iterAttr.IsNotNil() { + refs := iterAttr.AllReferences() + if len(refs) == 1 { + ctx.Set(idx, refs[0].TypeLabel(), "key") + ctx.Set(val, refs[0].TypeLabel(), "value") + } else { + e.debug.Log("Ignoring iterator attribute in dynamic block, expected one reference but got %d", len(refs)) + } + } + } + forEachFiltered = append(forEachFiltered, clone) values := clone.Values() diff --git a/pkg/iac/scanners/terraform/parser/parser_test.go b/pkg/iac/scanners/terraform/parser/parser_test.go index 10232b007fd9..1f13bbe41059 100644 --- a/pkg/iac/scanners/terraform/parser/parser_test.go +++ b/pkg/iac/scanners/terraform/parser/parser_test.go @@ -1745,3 +1745,39 @@ func TestTFVarsFileDoesNotExist(t *testing.T) { _, _, err := parser.EvaluateAll(context.TODO()) assert.ErrorContains(t, err, "file does not exist") } + +func TestDynamicWithIterator(t *testing.T) { + fsys := fstest.MapFS{ + "main.tf": &fstest.MapFile{ + Data: []byte(`resource "aws_s3_bucket" "this" { + dynamic versioning { + for_each = [true] + iterator = ver + + content { + enabled = ver.value + } + } +}`), + }, + } + + parser := New( + fsys, "", + OptionStopOnHCLError(true), + OptionWithDownloads(false), + ) + require.NoError(t, parser.ParseFS(context.TODO(), ".")) + + modules, _, err := parser.EvaluateAll(context.TODO()) + require.NoError(t, err) + + assert.Len(t, modules, 1) + + buckets := modules.GetResourcesByType("aws_s3_bucket") + assert.Len(t, buckets, 1) + + attr, _ := buckets[0].GetNestedAttribute("versioning.enabled") + + assert.True(t, attr.Value().True()) +}