diff --git a/checkov/terraform/checks/resource/base_resource_check.py b/checkov/terraform/checks/resource/base_resource_check.py index 1775c09d49a..926e58bada4 100644 --- a/checkov/terraform/checks/resource/base_resource_check.py +++ b/checkov/terraform/checks/resource/base_resource_check.py @@ -13,6 +13,7 @@ def __init__(self, name, id, categories, supported_resources): resource_registry.register(self) def scan_entity_conf(self, conf, entity_type): + self.handle_dynamic_values(conf) return self.scan_resource_conf(conf, entity_type) @multi_signature() @@ -32,3 +33,8 @@ def wrapper(self, conf, entity_type=None): return wrapped(self, conf) return wrapper + + def handle_dynamic_values(self, conf): + for dynamic_element in conf.get("dynamic", []): + for element_name in dynamic_element.keys(): + conf[element_name] = dynamic_element[element_name].get('content', []) diff --git a/checkov/terraform/checks/resource/base_resource_negative_value_check.py b/checkov/terraform/checks/resource/base_resource_negative_value_check.py index d48e73f28a7..94e2a5ba4f9 100644 --- a/checkov/terraform/checks/resource/base_resource_negative_value_check.py +++ b/checkov/terraform/checks/resource/base_resource_negative_value_check.py @@ -13,6 +13,8 @@ def __init__(self, name, id, categories, supported_resources): super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources) def scan_resource_conf(self, conf): + self.handle_dynamic_values(conf) + excluded_key = self.get_excluded_key() if excluded_key is not None: if dpath.search(conf, excluded_key) != {}: diff --git a/checkov/terraform/checks/resource/base_resource_value_check.py b/checkov/terraform/checks/resource/base_resource_value_check.py index e9085c9bd26..d312b4e1acb 100644 --- a/checkov/terraform/checks/resource/base_resource_value_check.py +++ b/checkov/terraform/checks/resource/base_resource_value_check.py @@ -40,6 +40,7 @@ def _is_nesting_key(inspected_attributes, key): return any([x in key for x in inspected_attributes]) def scan_resource_conf(self, conf): + self.handle_dynamic_values(conf) inspected_key = self.get_inspected_key() expected_values = self.get_expected_values() if dpath.search(conf, inspected_key) != {}: diff --git a/tests/terraform/checks/resource/aws/test_S3Encryption.py b/tests/terraform/checks/resource/aws/test_S3Encryption.py index eb9048af6a4..ffe7624b960 100644 --- a/tests/terraform/checks/resource/aws/test_S3Encryption.py +++ b/tests/terraform/checks/resource/aws/test_S3Encryption.py @@ -2,8 +2,8 @@ import hcl2 -from checkov.terraform.checks.resource.aws.S3Encryption import check from checkov.common.models.enums import CheckResult +from checkov.terraform.checks.resource.aws.S3Encryption import check class TestS3Encryption(unittest.TestCase): @@ -56,5 +56,45 @@ def test_success_oneline(self): scan_result = check.scan_resource_conf(conf=resource_conf) self.assertEqual(CheckResult.PASSED, scan_result) + def test_dynamic_value(self): + hcl_res = hcl2.loads(""" + resource "aws_s3_bucket" "default" { + count = local.enabled ? 1 : 0 + bucket = module.this.id + acl = "private" + force_destroy = var.force_destroy + tags = module.this.tags + + versioning { + enabled = var.versioning_enabled + } + + dynamic "logging" { + for_each = var.access_log_bucket_name != "" ? [1] : [] + content { + target_bucket = var.access_log_bucket_name + target_prefix = "logs/${module.this.id}/" + } + } + + dynamic "server_side_encryption_configuration" { + for_each = var.s3_bucket_encryption_enabled ? [1] : [] + + content { + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + } + } + } + + } + """) + resource_conf = hcl_res['resource'][0]['aws_s3_bucket']['default'] + scan_result = check.scan_resource_conf(conf=resource_conf) + self.assertEqual(CheckResult.PASSED, scan_result) + + if __name__ == '__main__': unittest.main()