Repository: bridgecrewio/checkov

Issue:
Azure App Service Environment - Ensure App Service Environment is zone redundant
**Describe the issue**
It seems that there is no checks to ensure that App Service Environment v3 are zone-redundant.

**Examples**

**Additional context**
````hcl
resource "azurerm_app_service_environment_v3" "example" {
  name                         = "example-asev3"
  resource_group_name = azurerm_resource_group.example.name
  subnet_id                  = azurerm_subnet.example.id
  zone_redundant       = true

  tags = {
    env         = "production"
    terraformed = "true"
  }
}
````

**Version (please complete the following information):**
N/A

**Additional context**

Applications deployed on a zonal ILB (Internally Load Balanced) ASE (App Service Environment) will continue to run and serve traffic on that ASE even if other zones in the same region suffer an outage. It is possible that non-runtime behaviors, including; application service plan scaling, application creation, application configuration, and application publishing may still be impacted from an outage in other availability zones.
Source : https://learn.microsoft.com/en-us/azure/app-service/environment/zone-redundancy


Discussion:

Resolving patch:
diff --git a/checkov/terraform/checks/resource/azure/AppServiceEnvironmentZoneRedundant.py b/checkov/terraform/checks/resource/azure/AppServiceEnvironmentZoneRedundant.py
new file mode 100644
--- /dev/null
+++ b/checkov/terraform/checks/resource/azure/AppServiceEnvironmentZoneRedundant.py
@@ -0,0 +1,17 @@
+from checkov.common.models.enums import CheckCategories
+from checkov.terraform.checks.resource.base_resource_value_check import BaseResourceValueCheck
+
+
+class AppServiceEnvironmentZoneRedundant(BaseResourceValueCheck):
+    def __init__(self) -> None:
+        name = "Ensure App Service Environment is zone redundant"
+        id = "CKV_AZURE_231"
+        supported_resources = ("azurerm_app_service_environment_v3",)
+        categories = (CheckCategories.BACKUP_AND_RECOVERY,)
+        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
+
+    def get_inspected_key(self) -> str:
+        return "zone_redundant"
+
+
+check = AppServiceEnvironmentZoneRedundant()


Test patch:
diff --git a/tests/terraform/checks/resource/azure/example_AppServiceEnvironmentZoneRedundant/main.tf b/tests/terraform/checks/resource/azure/example_AppServiceEnvironmentZoneRedundant/main.tf
new file mode 100644
--- /dev/null
+++ b/tests/terraform/checks/resource/azure/example_AppServiceEnvironmentZoneRedundant/main.tf
@@ -0,0 +1,34 @@
+resource "azurerm_app_service_environment_v3" "pass" {
+  name                = "example-asev3"
+  resource_group_name = azurerm_resource_group.example.name
+  subnet_id           = azurerm_subnet.example.id
+  zone_redundant      = true
+
+  tags = {
+    env         = "production"
+    terraformed = "true"
+  }
+}
+
+resource "azurerm_app_service_environment_v3" "fail1" {
+  name                = "example-asev3"
+  resource_group_name = azurerm_resource_group.example.name
+  subnet_id            = azurerm_subnet.example.id
+  zone_redundant       = false
+
+  tags = {
+    env         = "production"
+    terraformed = "true"
+  }
+}
+
+resource "azurerm_app_service_environment_v3" "fail2" {
+  name                = "example-asev3"
+  resource_group_name = azurerm_resource_group.example.name
+  subnet_id            = azurerm_subnet.example.id
+
+  tags = {
+    env         = "production"
+    terraformed = "true"
+  }
+}
\ No newline at end of file
diff --git a/tests/terraform/checks/resource/azure/test_AppServiceEnvironmentZoneRedundant.py b/tests/terraform/checks/resource/azure/test_AppServiceEnvironmentZoneRedundant.py
new file mode 100644
--- /dev/null
+++ b/tests/terraform/checks/resource/azure/test_AppServiceEnvironmentZoneRedundant.py
@@ -0,0 +1,42 @@
+import unittest
+from pathlib import Path
+
+from checkov.runner_filter import RunnerFilter
+from checkov.terraform.checks.resource.azure.AppServiceEnvironmentZoneRedundant import check
+from checkov.terraform.runner import Runner
+
+
+class TestAppServiceEnvironmentZoneRedundant(unittest.TestCase):
+    def test(self):
+        # given
+        test_files_dir = Path(__file__).parent / "example_AppServiceEnvironmentZoneRedundant"
+
+        # when
+        report = Runner().run(root_folder=str(test_files_dir), runner_filter=RunnerFilter(checks=[check.id]))
+
+        # then
+        summary = report.get_summary()
+
+        passing_resources = {
+            "azurerm_app_service_environment_v3.pass",
+        }
+        failing_resources = {
+            "azurerm_app_service_environment_v3.fail1",
+            "azurerm_app_service_environment_v3.fail2",
+        }
+        skipped_resources = {}
+
+        passed_check_resources = set([c.resource for c in report.passed_checks])
+        failed_check_resources = set([c.resource for c in report.failed_checks])
+
+        self.assertEqual(summary['passed'], len(passing_resources))
+        self.assertEqual(summary['failed'], len(failing_resources))
+        self.assertEqual(summary['skipped'], len(skipped_resources))
+        self.assertEqual(summary['parsing_errors'], 0)
+
+        self.assertEqual(passing_resources, passed_check_resources)
+        self.assertEqual(failing_resources, failed_check_resources)
+
+
+if __name__ == "__main__":
+    unittest.main()