Spurious violations when multiple resources at different paths share same identifier
- terrascan version: v1.13.2, v1.14.0, current master (2bf371dc640cca92d53adee0f8437bd76327f7d7)
- Operating System: macOS 12.2 (21D49), Docker container based on alpine:3.14 running on AWS
Description
I tried running terrascan on a terraform declaration referencing multiple different submodules that each declare a resource "aws_lambda_function" "this".
Actual behavior: When any of these resources violates a policy, all policies with the same resource type / name get flagged – even those that conform to the policy. Expected behavior: Only the resources that actually violate a policy should be reported.
What I Did / Steps to reproduce
- Open terrascan-spurious-violation-example.zip
- Inside the directory run
terrascan scan -i terraform --scan-rules="AC_AWS_0163"
Actual result
Violation Details -
Description : Lambda tracing is not enabled.
File : main.tf
Module Name : root
Plan Root : ./
Line : 15
Severity : LOW
-----------------------------------------------------------------------
Description : Lambda tracing is not enabled.
File : foo/main.tf
Module Name : foo
Plan Root : ./
Line : 1
Severity : LOW
-----------------------------------------------------------------------
Expected result
Violation Details -
Description : Lambda tracing is not enabled.
File : foo/main.tf
Module Name : foo
Plan Root : ./
Line : 1
Severity : LOW
-----------------------------------------------------------------------
Cause
- pkg/policy/opa/engine.go:417 relates the resource validations returned by the rego queries back to the input data by
id(FindAllResourcesByID) - pkg/iac-providers/terraform/commons/resource.go:60 defines the id for both resources as the same string
aws_lambda_function.this(viafmt.Sprintf("%s.%s", managedResource.Type, managedResource.Name))
Disambiguating the ID in the IAC provider (e.g. by including the tmp file name fmt.Sprintf("%s.%s.%s", managedResource.DeclRange.Filename, managedResource.Type, managedResource.Name)) caused terrascan to behave correctly.
It may however make more sense to define IDs to be the same as in the output of terraform plan. There the resource in main.tf is called aws_lambda_function.this whereas the one in foo/main.tf is referred to as module.foo.aws_lambda_function.this.