Skip to content

Commit

Permalink
fix(misconf): load cached tf modules (#6607)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin committed May 4, 2024
1 parent 9c794c0 commit 7a25dad
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 3 deletions.
5 changes: 5 additions & 0 deletions pkg/fanal/analyzer/config/terraform/terraform_test.go
Expand Up @@ -42,6 +42,11 @@ func TestConfigAnalyzer_Required(t *testing.T) {
filePath: "deployment.yaml",
want: false,
},
{
name: "manifest snapshot file",
filePath: ".terraform/modules/modules.json",
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions pkg/iac/detection/detect.go
Expand Up @@ -244,6 +244,10 @@ func init() {
}

func IsTerraformFile(path string) bool {
if strings.HasSuffix(path, filepath.ToSlash(".terraform/modules/modules.json")) {
return true
}

for _, ext := range []string{".tf", ".tf.json", ".tfvars"} {
if strings.HasSuffix(path, ext) {
return true
Expand Down
8 changes: 5 additions & 3 deletions pkg/iac/scanners/terraform/parser/load_module_metadata.go
Expand Up @@ -3,9 +3,11 @@ package parser
import (
"encoding/json"
"io/fs"
"path/filepath"
"path"
)

const manifestSnapshotFile = ".terraform/modules/modules.json"

type modulesMetadata struct {
Modules []struct {
Key string `json:"Key"`
Expand All @@ -16,13 +18,13 @@ type modulesMetadata struct {
}

func loadModuleMetadata(target fs.FS, fullPath string) (*modulesMetadata, string, error) {
metadataPath := filepath.Join(fullPath, ".terraform/modules/modules.json") // nolint: gocritic
metadataPath := path.Join(fullPath, manifestSnapshotFile)

f, err := target.Open(metadataPath)
if err != nil {
return nil, metadataPath, err
}
defer func() { _ = f.Close() }()
defer f.Close()

var metadata modulesMetadata
if err := json.NewDecoder(f).Decode(&metadata); err != nil {
Expand Down
4 changes: 4 additions & 0 deletions pkg/iac/scanners/terraform/parser/modules.go
Expand Up @@ -16,6 +16,10 @@ import (
// It builds a graph based on the module dependencies and determines the modules that have no incoming dependencies,
// considering them as root modules.
func (p *Parser) FindRootModules(ctx context.Context, dirs []string) ([]string, error) {
// skip cached terraform modules as they cannot be root modules
dirs = lo.Filter(dirs, func(dir string, _ int) bool {
return !strings.Contains(dir, ".terraform/modules/")
})
for _, dir := range dirs {
if err := p.ParseFS(ctx, dir); err != nil {
return nil, err
Expand Down
25 changes: 25 additions & 0 deletions pkg/iac/scanners/terraform/parser/parser_test.go
Expand Up @@ -3,6 +3,7 @@ package parser
import (
"context"
"os"
"path/filepath"
"sort"
"testing"

Expand Down Expand Up @@ -1699,3 +1700,27 @@ resource "test" "values" {
"a": cty.NumberIntVal(1), "b": cty.NumberIntVal(2),
})))
}

func Test_LoadLocalCachedModule(t *testing.T) {
fsys := os.DirFS(filepath.Join("testdata", "cached-modules"))

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, 2)

buckets := modules.GetResourcesByType("aws_s3_bucket")
assert.Len(t, buckets, 1)

assert.Equal(t, "my-private-module/s3-bucket/aws/.terraform/modules/s3-bucket/main.tf", buckets[0].GetMetadata().Range().GetFilename())

bucketName := buckets[0].GetAttribute("bucket").Value().AsString()
assert.Equal(t, "my-s3-bucket", bucketName)
}
@@ -0,0 +1 @@
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"s3-bucket","Source":"registry.myregistry.org/my-private-module/s3-bucket/aws","Version":"1.0.0","Dir":".terraform/modules/s3-bucket"}]}
@@ -0,0 +1,7 @@
variable "bucket" {
type = string
}

resource "aws_s3_bucket" "this" {
bucket = var.bucket
}
@@ -0,0 +1,5 @@
module "s3-bucket" {
source = "my-private-module/s3-bucket/aws"
version = "1.0.0"
bucket = "my-s3-bucket"
}

0 comments on commit 7a25dad

Please sign in to comment.