Repository: bridgecrewio/checkov

Issue:
CKV_AZURE_23 - Reports incorrect fail when using azurerm_mssql_server_extended_auditing_policy
Check: CKV_AZURE_23: "Ensure that 'Auditing' is set to 'On' for SQL servers"
        FAILED for resource: azurerm_mssql_server.server
        File: /sql_server.tf:19-37
        Guide: https://docs.bridgecrew.io/docs/bc_azr_logging_2

                19 | resource "azurerm_mssql_server" "server" {
                20 |   name                          = "${var.org_short}-${var.env_short}-${var.loc_short}-${var.service}-mssql"
                21 |   location                      = var.location
                22 |   resource_group_name           = azurerm_resource_group.server.name
                23 |   version                       = var.sql_server_server_version
                24 |   administrator_login           = "${var.org_short}-${var.env_short}-${var.loc_short}-${var.service}-mssql-admin"
                25 |   administrator_login_password  = random_password.server.result
                26 |   minimum_tls_version           = var.min_tls_version
                27 |   public_network_access_enabled = false
                28 |   azuread_administrator {
                29 |     login_username = "AzureAD Admin"
                30 |     object_id      = data.azuread_group.sqldba.object_id
                31 |     tenant_id      = data.azurerm_client_config.current.tenant_id
                32 |   }
                33 |   identity {
                34 |     type = "SystemAssigned"
                35 |   }
                36 |   tags = local.default_tags
                37 | }

When using Checkov v1.0.861

However
The auditing policy is set by the separate resource azurerm_mssql_server_extended_auditing_policy

```
resource "azurerm_mssql_server_extended_auditing_policy" "server" {
  server_id                                                     = azurerm_mssql_server.server.id
  log_monitoring_enabled                            = true
  storage_endpoint                                       = azurerm_storage_account.server.primary_blob_endpoint
  storage_account_access_key                       = azurerm_storage_account.server.primary_access_key
  storage_account_access_key_is_secondary = true
  retention_in_days                                        = var.log_rention_policy_days
}
```






Discussion:
`azurerm_mssql_server` allows setting the Extended Auditing Policy using either the [`extended_auditing_policy` argument](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server#extended_auditing_policy) or the [`mssql_server_extended_auditing_policy` resource](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server_extended_auditing_policy). Currently `checkov` only supports the former use case.

Supporting [mssql_server_extended_auditing_policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server_extended_auditing_policy) will be difficult to implement, as each check is run on each resource, and the check registry does not pass/expose all the resources/entities to the checks.
I see that in #155 that the feature to correlate multiple resources has been added in #1023, is there any example of how to do so? The #1023 PR is too big to go through

Resolving patch:
diff --git a/checkov/terraform/checks/resource/azure/SQLServerAuditingEnabled.py b/checkov/terraform/checks/resource/azure/SQLServerAuditingEnabled.py
deleted file mode 100644
--- a/checkov/terraform/checks/resource/azure/SQLServerAuditingEnabled.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from checkov.common.models.enums import CheckCategories
-from checkov.terraform.checks.resource.base_resource_value_check import BaseResourceValueCheck
-from checkov.common.models.consts import ANY_VALUE
-
-
-class SQLServerAuditingEnabled(BaseResourceValueCheck):
-    def __init__(self):
-        name = "Ensure that 'Auditing' is set to 'On' for SQL servers"
-        id = "CKV_AZURE_23"
-        supported_resources = ['azurerm_sql_server', 'azurerm_mssql_server']
-        categories = [CheckCategories.LOGGING]
-        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
-
-    def get_inspected_key(self):
-        return 'extended_auditing_policy'
-
-    def get_expected_value(self):
-        return ANY_VALUE
-
-
-check = SQLServerAuditingEnabled()


Test patch:
diff --git a/tests/terraform/checks/resource/azure/test_SQLServerAuditingEnabled.py b/tests/terraform/checks/resource/azure/test_SQLServerAuditingEnabled.py
deleted file mode 100644
--- a/tests/terraform/checks/resource/azure/test_SQLServerAuditingEnabled.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import unittest
-
-import hcl2
-
-from checkov.terraform.checks.resource.azure.SQLServerAuditingEnabled import check
-from checkov.common.models.enums import CheckResult
-
-
-class TestSQLServerAuditingEnabled(unittest.TestCase):
-
-    def test_failure(self):
-        hcl_res = hcl2.loads("""
-            resource "azurerm_sql_server" "example" {
-              name                         = "mssqlserver"
-              resource_group_name          = azurerm_resource_group.example.name
-              location                     = azurerm_resource_group.example.location
-              version                      = "12.0"
-              administrator_login          = "mradministrator"
-              administrator_login_password = "thisIsDog11"
-              }
-                """)
-        resource_conf = hcl_res['resource'][0]['azurerm_sql_server']['example']
-        scan_result = check.scan_resource_conf(conf=resource_conf)
-        self.assertEqual(CheckResult.FAILED, scan_result)
-
-    def test_success(self):
-        hcl_res = hcl2.loads("""
-            resource "azurerm_sql_server" "example" {
-              name                         = "mssqlserver"
-              resource_group_name          = azurerm_resource_group.example.name
-              location                     = azurerm_resource_group.example.location
-              version                      = "12.0"
-              administrator_login          = "mradministrator"
-              administrator_login_password = "thisIsDog11"
-
-              extended_auditing_policy {
-                storage_endpoint                        = azurerm_storage_account.example.primary_blob_endpoint
-                storage_account_access_key              = azurerm_storage_account.example.primary_access_key
-                storage_account_access_key_is_secondary = true
-                retention_in_days                       = 6
-              }
-              }
-                """)
-        resource_conf = hcl_res['resource'][0]['azurerm_sql_server']['example']
-        scan_result = check.scan_resource_conf(conf=resource_conf)
-        self.assertEqual(CheckResult.PASSED, scan_result)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/tests/terraform/graph/checks/resources/SQLServerAuditingEnabled/expected.yaml b/tests/terraform/graph/checks/resources/SQLServerAuditingEnabled/expected.yaml
new file mode 100644
--- /dev/null
+++ b/tests/terraform/graph/checks/resources/SQLServerAuditingEnabled/expected.yaml
@@ -0,0 +1,7 @@
+pass:
+  - "azurerm_sql_server.success"
+  - "azurerm_mssql_server.success"
+  - "azurerm_mssql_server.inline_success"
+fail:
+  - "azurerm_sql_server.failure"
+  - "azurerm_mssql_server.failure"
diff --git a/tests/terraform/graph/checks/resources/SQLServerAuditingEnabled/main.tf b/tests/terraform/graph/checks/resources/SQLServerAuditingEnabled/main.tf
new file mode 100644
--- /dev/null
+++ b/tests/terraform/graph/checks/resources/SQLServerAuditingEnabled/main.tf
@@ -0,0 +1,66 @@
+resource "azurerm_sql_server" "failure" {
+  name                         = "mssqlserver"
+  resource_group_name          = azurerm_resource_group.example.name
+  location                     = azurerm_resource_group.example.location
+  version                      = "12.0"
+  administrator_login          = "mradministrator"
+  administrator_login_password = "thisIsDog11"
+}
+
+resource "azurerm_sql_server" "success" {
+  name                         = "mssqlserver"
+  resource_group_name          = azurerm_resource_group.example.name
+  location                     = azurerm_resource_group.example.location
+  version                      = "12.0"
+  administrator_login          = "mradministrator"
+  administrator_login_password = "thisIsDog11"
+
+  extended_auditing_policy {
+    storage_endpoint                        = azurerm_storage_account.example.primary_blob_endpoint
+    storage_account_access_key              = azurerm_storage_account.example.primary_access_key
+    storage_account_access_key_is_secondary = true
+    retention_in_days                       = 6
+  }
+}
+
+resource "azurerm_mssql_server" "failure" {
+  name                         = "mssqlserver"
+  resource_group_name          = azurerm_resource_group.example.name
+  location                     = azurerm_resource_group.example.location
+  version                      = "12.0"
+  administrator_login          = "mradministrator"
+  administrator_login_password = "thisIsDog11"
+}
+
+resource "azurerm_mssql_server" "success" {
+  name                         = "mssqlserver"
+  resource_group_name          = azurerm_resource_group.example.name
+  location                     = azurerm_resource_group.example.location
+  version                      = "12.0"
+  administrator_login          = "mradministrator"
+  administrator_login_password = "thisIsDog11"
+
+  extended_auditing_policy {
+    storage_endpoint                        = azurerm_storage_account.example.primary_blob_endpoint
+    storage_account_access_key              = azurerm_storage_account.example.primary_access_key
+    storage_account_access_key_is_secondary = true
+    retention_in_days                       = 6
+  }
+}
+
+resource "azurerm_mssql_server" "inline_success" {
+  name                         = "mssqlserver"
+  resource_group_name          = azurerm_resource_group.example.name
+  location                     = azurerm_resource_group.example.location
+  version                      = "12.0"
+  administrator_login          = "mradministrator"
+  administrator_login_password = "thisIsDog11"
+}
+
+resource "azurerm_mssql_server_extended_auditing_policy" "extended_auditing_policy" {
+  server_id                               = azurerm_mssql_server.inline_success.id
+  storage_endpoint                        = azurerm_storage_account.example.primary_blob_endpoint
+  storage_account_access_key              = azurerm_storage_account.example.primary_access_key
+  storage_account_access_key_is_secondary = true
+  retention_in_days                       = 6
+}
diff --git a/tests/terraform/graph/checks/test_yaml_policies.py b/tests/terraform/graph/checks/test_yaml_policies.py
--- a/tests/terraform/graph/checks/test_yaml_policies.py
+++ b/tests/terraform/graph/checks/test_yaml_policies.py
@@ -188,6 +188,9 @@ def test_ALBProtectedByWAF(self):
     def test_APIProtectedByWAF(self):
         self.go("APIProtectedByWAF")
 
+    def test_SQLServerAuditingEnabled(self):
+        self.go("SQLServerAuditingEnabled")
+
     def test_registry_load(self):
         registry = Registry(parser=NXGraphCheckParser(), checks_dir=str(
             Path(__file__).parent.parent.parent.parent.parent / "checkov" / "terraform" / "checks" / "graph_checks"))
diff --git a/tests/terraform/runner/test_runner.py b/tests/terraform/runner/test_runner.py
--- a/tests/terraform/runner/test_runner.py
+++ b/tests/terraform/runner/test_runner.py
@@ -228,12 +228,14 @@ def test_no_missing_ids(self):
 
         azure_checks = sorted(list(filter(lambda check_id: '_AZURE_' in check_id, unique_checks)), reverse=True, key=lambda s: int(s.split('_')[-1]))
         for i in range(1, len(azure_checks) + 1):
+            if f'CKV_AZURE_{i}' == 'CKV_AZURE_23':
+                continue  # this rule has been refactored into a v2 graph implementation
             if f'CKV_AZURE_{i}' == 'CKV_AZURE_43':
                 continue  # Pending merge; blocked by another issue https://github.com/bridgecrewio/checkov/pull/429
             if f'CKV_AZURE_{i}' == 'CKV_AZURE_51':
                 continue  # https://github.com/bridgecrewio/checkov/pull/983
             if f'CKV_AZURE_{i}' == 'CKV_AZURE_119':
-                continue  # this rules has been refactored into a v2 graph implementation
+                continue  # this rule has been refactored into a v2 graph implementation
 
             self.assertIn(f'CKV_AZURE_{i}', azure_checks,
                           msg=f'The new Azure violation should have the ID "CKV_AZURE_{i}"')