Skip to content

Commit

Permalink
fix(terraform_plan): Edges not created because of indexing in resourc…
Browse files Browse the repository at this point in the history
…e["address"] when resources in modules use count (#6145)

* plan_parser fix resource address

fix resource[address] in plan_parser

* add test cases

* fix testcase error
  • Loading branch information
sourava01 authored May 2, 2024
1 parent a0e6c2c commit 46d7f22
Show file tree
Hide file tree
Showing 8 changed files with 6,258 additions and 8 deletions.
18 changes: 11 additions & 7 deletions checkov/terraform/graph_builder/local_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,19 +479,23 @@ def _find_vertex_with_best_match(self, relevant_vertices_indexes: List[int], ori
vertex_realpath = os.path.realpath(vertex.path)
self._vertex_path_to_realpath_cache[vertex.path] = vertex_realpath
common_prefix = os.path.commonpath([vertex_realpath, origin_real_path])

# checks if module name is same for dest and origin vertex.
if origin_vertex_index is not None:
vertex_module_name = vertex.attributes.get(CustomAttributes.TF_RESOURCE_ADDRESS, '')
origin_module_name = self.vertices[origin_vertex_index].attributes.get(CustomAttributes.TF_RESOURCE_ADDRESS, '')
if vertex_module_name.startswith(BlockType.MODULE) and origin_module_name.startswith(BlockType.MODULE):
split_module_name = vertex_module_name.split('.')[1]
if origin_module_name.startswith(f'{BlockType.MODULE}.{split_module_name}'):
common_prefix = f"{common_prefix} {BlockType.MODULE}.{split_module_name}"

if len(common_prefix) > len(longest_common_prefix):
vertex_index_with_longest_common_prefix = vertex_index
longest_common_prefix = common_prefix
vertices_with_longest_common_prefix = [(vertex_index, vertex)]
elif len(common_prefix) == len(longest_common_prefix):
vertices_with_longest_common_prefix.append((vertex_index, vertex))
if origin_vertex_index is not None:
vertex_module_name = vertex.attributes.get(CustomAttributes.TF_RESOURCE_ADDRESS, '')
origin_module_name = self.vertices[origin_vertex_index].attributes.get(CustomAttributes.TF_RESOURCE_ADDRESS, '')
if vertex_module_name.startswith(BlockType.MODULE) and origin_module_name.startswith(BlockType.MODULE):
split_module_name = vertex_module_name.split('.')[1]
if origin_module_name.startswith(f'{BlockType.MODULE}.{split_module_name}'):
vertex_index_with_longest_common_prefix = vertex_index

if len(vertices_with_longest_common_prefix) <= 1:
return vertex_index_with_longest_common_prefix

Expand Down
2 changes: 1 addition & 1 deletion checkov/terraform/plan_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def _find_child_modules(
(
module_call_resource
for module_call_resource in module_call_resources
if f"{module_address}.{module_call_resource['address']}" == resource["address"]
if f"{module_address}.{module_call_resource['address']}" == (resource["address"].rsplit('[', 1)[0] if resource["address"][-1] == "]" else resource["address"])
),
None
)
Expand Down
8 changes: 8 additions & 0 deletions tests/terraform/graph/graph_builder/test_graph_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from checkov.terraform.graph_manager import TerraformGraphManager
from checkov.common.graph.graph_builder import CustomAttributes
from checkov.terraform.modules.module_utils import external_modules_download_path
from checkov.terraform.plan_utils import create_definitions

TEST_DIRNAME = os.path.dirname(os.path.realpath(__file__))

Expand Down Expand Up @@ -372,6 +373,13 @@ def test_build_rustworkx_graph(self):
self.check_edge(graph, resource_node, var_region_node, 'region')
self.check_edge(graph, provider_node, var_aws_profile_node, 'profile')
self.check_edge(graph, local_node, var_bucket_name_node, 'bucket_name')

def test_multiple_modules_with_connected_resources(self):
valid_plan_path = os.path.realpath(os.path.join(TEST_DIRNAME, '../resources/modules_edges_tfplan/tfplan.json'))
definitions, definitions_raw = create_definitions(root_folder=None, files=[valid_plan_path])
graph_manager = TerraformGraphManager(db_connector=RustworkxConnector())
tf_plan_local_graph = graph_manager.build_graph_from_definitions(definitions, render_variables=False)
self.assertTrue(tf_plan_local_graph.in_edges[2])


def build_new_key_for_tf_definition(key):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module "s3-bucket-1" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "4.0.1"
}

module "s3-bucket-2" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "4.0.1"
}
Loading

0 comments on commit 46d7f22

Please sign in to comment.