Skip to content

Commit

Permalink
feat(misconf): generate placeholders for random provider resources (#…
Browse files Browse the repository at this point in the history
…8051)

Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io>
  • Loading branch information
nikpivkin authored Dec 6, 2024
1 parent fd07074 commit ffe24e1
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
44 changes: 44 additions & 0 deletions pkg/iac/scanners/terraform/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strconv"
"strings"
"testing"
"testing/fstest"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -951,3 +952,46 @@ resource "aws_s3_bucket" "test" {}
assert.Len(t, results, 2)
})
}

func TestUseRandomProvider(t *testing.T) {
fsys := fstest.MapFS{
"main.tf": &fstest.MapFile{Data: []byte(`resource "random_id" "suffix" {}
locals {
bucket = "test-${random_id.suffix.hex}"
}
resource "aws_s3_bucket" "test" {
bucket = local.bucket
}
resource "aws_s3_bucket_versioning" "test" {
bucket = local.bucket
versioning_configuration {
status = "Enabled"
}
}
`)},
}

check := `package test
import rego.v1
deny contains res if {
some bucket in input.aws.s3.buckets
bucket.versioning.enabled.value
res := result.new("Bucket versioning is enabled", bucket)
}
`

scanner := New(
ScannerWithAllDirectories(true),
rego.WithPolicyReader(strings.NewReader(check)),
rego.WithPolicyNamespaces("test"),
)

results, err := scanner.ScanFS(context.TODO(), fsys, ".")
require.NoError(t, err)

assert.Len(t, results.GetFailed(), 1)
}
24 changes: 20 additions & 4 deletions pkg/iac/terraform/presets.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@ package terraform

import (
"fmt"
"math/rand/v2"
"strings"

"github.com/google/uuid"
"github.com/zclconf/go-cty/cty"
)

var resourceRandomAttributes = map[string][]string{
// If the user leaves the name blank, Terraform will automatically generate a unique name
"aws_launch_template": {"name"},
"random_id": {"hex", "dec", "b64_url", "b64_std"},
"random_password": {"result", "bcrypt_hash"},
"random_string": {"result"},
"random_bytes": {"base64", "hex"},
"random_uuid": {"result"},
}

func createPresetValues(b *Block) map[string]cty.Value {
presets := make(map[string]cty.Value)

Expand All @@ -23,16 +34,21 @@ func createPresetValues(b *Block) map[string]cty.Value {
// workaround for weird iam feature
case "aws_iam_policy_document":
presets["json"] = cty.StringVal(b.ID())
// If the user leaves the name blank, Terraform will automatically generate a unique name
case "aws_launch_template":
presets["name"] = cty.StringVal(uuid.New().String())
// allow referencing the current region name
case "aws_region":
presets["name"] = cty.StringVal("current-region")
case "random_integer":
//nolint:gosec
presets["result"] = cty.NumberIntVal(rand.Int64())
}

return presets
if attrs, exists := resourceRandomAttributes[b.TypeLabel()]; exists {
for _, attr := range attrs {
presets[attr] = cty.StringVal(uuid.New().String())
}
}

return presets
}

func postProcessValues(b *Block, input map[string]cty.Value) map[string]cty.Value {
Expand Down

0 comments on commit ffe24e1

Please sign in to comment.