Repository: bridgecrewio/checkov

Issue:
CKV_AWS_233 Ensure Create before destroy for ACM certificates false positive reading plan
**Describe the issue**
This check raises a false positive for the following resource which does have that lifecycle hook enabled.

**Examples**

Checkov run with:

```
checkov --file plan.json --output junitxml --output cli --output-file-path checkov-out --repo-root-for-plan-enrichment . --download-external-modules True > out.log 2>&1
```

Section in the plan.json:

```
{
  "address": "module.my_module.aws_acm_certificate.my_cert",
  "mode": "managed",
  "type": "aws_acm_certificate",
  "name": "my_cert",
  "provider_name": "registry.terraform.io/hashicorp/aws",
  "schema_version": 0,
  "values": {
    "arn": "CENSORED",
    "certificate_authority_arn": "",
    "certificate_body": null,
    "certificate_chain": null,
    "domain_name": "CENSORED",
    "domain_validation_options": [
      {
        "domain_name": "CENSORED",
        "resource_record_name": "CENSORED",
        "resource_record_type": "CNAME",
        "resource_record_value": "CENSORED"
      }
    ],
    "id": "CENSORED",
    "options": [
      {
        "certificate_transparency_logging_preference": "ENABLED"
      }
    ],
    "private_key": null,
    "status": "ISSUED",
    "subject_alternative_names": [
      "CENSORED"
    ],
    "tags": {},
    "tags_all": {},
    "validation_emails": [],
    "validation_method": "DNS",
    "validation_option": []
  },
  "sensitive_values": {
    "domain_validation_options": [
      {}
    ],
    "options": [
      {}
    ],
    "subject_alternative_names": [
      false
    ],
    "tags": {},
    "tags_all": {},
    "validation_emails": [],
    "validation_option": []
  }
}

```

Terraform code:

```terraform
resource "aws_acm_certificate" "my_cert" {
  domain_name       = local.domain_name
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}
```

Error:

```
Check: CKV_AWS_233: "Ensure Create before destroy for ACM certificates"
	FAILED for resource: aws_acm_certificate.my_cert
	File: ../my-file.tf:1-8

		1 | resource "aws_acm_certificate" "my_cert" {
		2 |   domain_name       = local.domain_name
		3 |   validation_method = "DNS"
		4 | 
		5 |   lifecycle {
		6 |     create_before_destroy = true
		7 |   }
		8 | }
```

**Version:**
 - Checkov Version: 2.0.1200

**Additional context**
Add any other context about the problem here.



Discussion:
hey @jSherz thanks for reporting it. It looks like that Terraform only applies `lifecycle` rules on client side, so it doesn't store it in the plan, that's why the check fails. I will check, if we can skip the check for Terraform plan scans.

Resolving patch:
diff --git a/checkov/terraform/plan_runner.py b/checkov/terraform/plan_runner.py
--- a/checkov/terraform/plan_runner.py
+++ b/checkov/terraform/plan_runner.py
@@ -20,6 +20,14 @@
 from checkov.terraform.plan_utils import create_definitions, build_definitions_context
 from checkov.terraform.runner import Runner as TerraformRunner, merge_reports
 
+# set of check IDs with lifecycle condition
+TF_LIFECYCLE_CHECK_IDS = {
+    "CKV_AWS_217",
+    "CKV_AWS_233",
+    "CKV_AWS_237",
+    "CKV_GCP_82",
+}
+
 
 class Runner(TerraformRunner):
     check_type = CheckType.TERRAFORM_PLAN
@@ -101,6 +109,10 @@ def run_block(self, entities,
 
                 results = registry.scan(scanned_file, entity, [], runner_filter)
                 for check, check_result in results.items():
+                    if check.id in TF_LIFECYCLE_CHECK_IDS:
+                        # can't be evaluated in TF plan
+                        continue
+
                     record = Record(check_id=check.id, bc_check_id=check.bc_id, check_name=check.name,
                                     check_result=check_result,
                                     code_block=entity_code_lines, file_path=scanned_file,


Test patch:
diff --git a/tests/terraform/runner/resources/plan_with_lifecycle_check/tfplan.json b/tests/terraform/runner/resources/plan_with_lifecycle_check/tfplan.json
new file mode 100644
Binary files /dev/null and b/tests/terraform/runner/resources/plan_with_lifecycle_check/tfplan.json differ
diff --git a/tests/terraform/runner/test_plan_runner.py b/tests/terraform/runner/test_plan_runner.py
--- a/tests/terraform/runner/test_plan_runner.py
+++ b/tests/terraform/runner/test_plan_runner.py
@@ -571,6 +571,21 @@ def test_runner_line_numbers(self):
         failed_check = report.failed_checks[0]
         self.assertEqual(failed_check.file_line_range, [13, 19])
 
+    def test_runner_ignore_lifecycle_checks(self):
+        # given
+        tf_file_path = Path(__file__).parent / "resources/plan_with_lifecycle_check/tfplan.json"
+
+        # when
+        report = Runner().run(
+            root_folder=None,
+            files=[str(tf_file_path)],
+            external_checks_dir=None,
+            runner_filter=RunnerFilter(framework=["terraform_plan"]),
+        )
+
+        # then
+        self.assertEqual(len(report.failed_checks), 0)
+
     def tearDown(self) -> None:
         resource_registry.checks = self.orig_checks