Skip to content

Commit

Permalink
fix(terraform): Fix CKV_AZURE_227 for Azure V4 (#6906)
Browse files Browse the repository at this point in the history
* Fix CKV_AZURE_227

* Fix CKV_AZURE_145

* fix flake8

* add flexible servers

* fix flake8

* Fix CKV_AZURE_11

* Update checks

* Update check

* Update check

* Add types
  • Loading branch information
tsmithv11 authored Dec 16, 2024
1 parent fac2c72 commit 7e0f74f
Show file tree
Hide file tree
Showing 23 changed files with 368 additions and 77 deletions.
2 changes: 1 addition & 1 deletion checkov/arm/checks/resource/FunctionAppMinTLSVersion.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def get_expected_value(self) -> Any:
return 1.2

def get_expected_values(self) -> List[Any]:
return ["1.2", 1.2]
return ["1.2", 1.2, "1.3", 1.3]


check = FunctionAppMinTLSVersion()
15 changes: 10 additions & 5 deletions checkov/arm/checks/resource/MySQLPublicAccessDisabled.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from checkov.common.models.enums import CheckCategories
from checkov.arm.base_resource_value_check import BaseResourceValueCheck

Expand All @@ -6,18 +8,21 @@ class MySQLPublicAccessDisabled(BaseResourceValueCheck):
def __init__(self) -> None:
name = "Ensure 'public network access enabled' is set to 'False' for mySQL servers"
id = "CKV_AZURE_53"
supported_resources = ("Microsoft.DBforMySQL/servers",)
supported_resources = ("Microsoft.DBforMySQL/servers", "Microsoft.DBforMySQL/flexibleServers",)
categories = (CheckCategories.NETWORKING,)
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)

def get_inspected_key(self) -> str:
return "properties/publicNetworkAccess"
if self.entity_type == "Microsoft.DBforMySQL/servers":
return "properties/publicNetworkAccess"
else:
return "properties/network/publicNetworkAccess"

def get_expected_value(self) -> str:
"""
Returns the default expected value, governed by provider best practices
"""
return "disabled"

def get_expected_values(self) -> List[str]:
return ["disabled", "Disabled"]


check = MySQLPublicAccessDisabled()
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ metadata:
definition:
or:
- cond_type: "attribute"
resource_types: "azurerm_sql_firewall_rule"
resource_types:
- "azurerm_sql_firewall_rule"
- "azurerm_mssql_firewall_rule"
attribute: "start_ip_address"
operator: "not_equals"
value: "0.0.0.0"

- cond_type: "attribute"
resource_types: "azurerm_sql_firewall_rule"
resource_types:
- "azurerm_sql_firewall_rule"
- "azurerm_mssql_firewall_rule"
attribute: "end_ip_address"
operator: "not_equals"
value: "0.0.0.0"
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ definition:
attribute: resource_type
value:
- azurerm_sql_server
- azurerm_mssql_server
operator: within
- resource_types:
- azurerm_sql_server
- azurerm_mssql_server
connected_resource_types:
- azurerm_mssql_server_security_alert_policy
operator: exists
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from checkov.common.models.enums import CheckCategories, CheckResult
from checkov.terraform.checks.resource.base_resource_value_check import BaseResourceValueCheck
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck


class AKSEncryptionAtHostEnabled(BaseResourceValueCheck):
class AKSEncryptionAtHostEnabled(BaseResourceCheck):
def __init__(self) -> None:
"""
With host-based encryption, the data stored on the VM host of
Expand All @@ -22,14 +22,23 @@ def __init__(self) -> None:
id=id,
categories=categories,
supported_resources=supported_resources,
missing_block_result=CheckResult.FAILED,
)

def get_inspected_key(self) -> str:
def scan_resource_conf(self, conf) -> CheckResult:
if self.entity_type == "azurerm_kubernetes_cluster":
return "default_node_pool/[0]/enable_host_encryption"
if conf.get('default_node_pool'):
node_pool = conf['default_node_pool'][0]
if (node_pool.get('enable_host_encryption') == [True] or
node_pool.get('host_encryption_enabled') == [True]):
return CheckResult.PASSED
self.evaluated_keys = ['default_node_pool/[0]/enable_host_encryption',
'default_node_pool/[0]/host_encryption_enabled']
else:
return "enable_host_encryption"
if conf.get('enable_host_encryption') == [True] or conf.get('host_encryption_enabled') == [True]:
return CheckResult.PASSED
self.evaluated_keys = ['enable_host_encryption', 'host_encryption_enabled']

return CheckResult.FAILED


check = AKSEncryptionAtHostEnabled()
25 changes: 16 additions & 9 deletions checkov/terraform/checks/resource/azure/AKSNodePublicIpDisabled.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
from checkov.common.models.enums import CheckCategories
from checkov.terraform.checks.resource.base_resource_negative_value_check import BaseResourceNegativeValueCheck
from typing import List, Any
from typing import Dict, List, Any

from checkov.common.models.enums import CheckCategories, CheckResult
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck

class AKSNodePublicIpDisabled(BaseResourceNegativeValueCheck):
def __init__(self):

class AKSNodePublicIpDisabled(BaseResourceCheck):
def __init__(self) -> None:
name = "Ensure AKS cluster nodes do not have public IP addresses"
id = "CKV_AZURE_143"
supported_resources = ['azurerm_kubernetes_cluster']
categories = [CheckCategories.NETWORKING]
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)

def get_inspected_key(self) -> str:
return "default_node_pool/[0]/enable_node_public_ip"
def scan_resource_conf(self, conf: Dict[str, List[Any]]) -> CheckResult:
if 'default_node_pool' in conf:
default_node_pool = conf['default_node_pool'][0]
if isinstance(default_node_pool, dict):
if default_node_pool.get('enable_node_public_ip') == [True] or default_node_pool.get('node_public_ip_enabled') == [True]:
return CheckResult.FAILED

return CheckResult.PASSED

def get_forbidden_values(self) -> List[Any]:
return [True]
def get_evaluated_keys(self) -> List[str]:
return ['default_node_pool/[0]/enable_node_public_ip', 'default_node_pool/[0]/node_public_ip_enabled']


check = AKSNodePublicIpDisabled()
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from typing import Any, List

from checkov.common.models.enums import CheckResult, CheckCategories
from checkov.terraform.checks.resource.base_resource_value_check import BaseResourceValueCheck


class FunctionAppMinTLSVersion(BaseResourceValueCheck):
def __init__(self):
def __init__(self) -> None:
"""
The minimum supported TLS version for the function app.
Defaults to 1.2 for new function apps.
Expand All @@ -20,17 +22,17 @@ def __init__(self):
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources,
missing_block_result=CheckResult.PASSED)

def get_inspected_key(self):
def get_inspected_key(self) -> str:
if self.entity_type in ("azurerm_function_app", "azurerm_function_app_slot"):
return "site_config/[0]/min_tls_version"
else:
return "site_config/[0]/minimum_tls_version"

def get_expected_value(self):
def get_expected_value(self) -> float:
return 1.2

def get_expected_values(self):
return ["1.2", 1.2]
def get_expected_values(self) -> List[Any]:
return ["1.2", 1.2, "1.3", 1.3]


check = FunctionAppMinTLSVersion()
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def __init__(self):
'azurerm_sql_firewall_rule',
'azurerm_postgresql_firewall_rule',
'azurerm_mysql_firewall_rule',
'azurerm_mysql_flexible_server_firewall_rule',
'azurerm_mssql_firewall_rule',
)
categories = (CheckCategories.NETWORKING,)
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', 'example-app-service-plan')]",
"siteConfig": {
"minTlsVersion": 1.2
"minTlsVersion": 1.3
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.DBforMySQL/flexibleServers",
"apiVersion": "2024-10-01-preview",
"name": "fail2",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity": {}
}
},
"location": "eastus",
"properties": {
"administratorLogin": "adminuser",
"administratorLoginPassword": "YourSecurePassword123!",
"availabilityZone": "1",
"backup": {
"backupIntervalHours": 24,
"backupRetentionDays": 7,
"geoRedundantBackup": "Disabled"
},
"createMode": "Default",
"databasePort": 3306,
"dataEncryption": {
"type": "SystemManaged"
},
"highAvailability": {
"mode": "ZoneRedundant",
"standbyAvailabilityZone": "2"
},
"maintenancePolicy": {
"patchStrategy": "Automatic"
},
"maintenanceWindow": {
"customWindow": "Sun:02:00-Sun:04:00",
"dayOfWeek": 0,
"startHour": 2,
"startMinute": 0
},
"network": {
"delegatedSubnetResourceId": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet",
"privateDnsZoneResourceId": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/myPrivateDnsZone",
"publicNetworkAccess": "Enabled"
},
"storage": {
"autoGrow": "Enabled",
"iops": 600,
"storageSizeGB": 128,
"storageRedundancy": "Zone"
},
"version": "8.0"
},
"sku": {
"name": "Standard_D2ds_v4",
"tier": "GeneralPurpose"
},
"tags": {
"Environment": "Production",
"Project": "MySQLMigration"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.DBforMySQL/flexibleServers",
"apiVersion": "2024-10-01-preview",
"name": "pass2",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity": {}
}
},
"location": "eastus",
"properties": {
"administratorLogin": "adminuser",
"administratorLoginPassword": "YourSecurePassword123!",
"availabilityZone": "1",
"backup": {
"backupIntervalHours": 24,
"backupRetentionDays": 7,
"geoRedundantBackup": "Disabled"
},
"createMode": "Default",
"databasePort": 3306,
"dataEncryption": {
"type": "SystemManaged"
},
"highAvailability": {
"mode": "ZoneRedundant",
"standbyAvailabilityZone": "2"
},
"maintenancePolicy": {
"patchStrategy": "Automatic"
},
"maintenanceWindow": {
"customWindow": "Sun:02:00-Sun:04:00",
"dayOfWeek": 0,
"startHour": 2,
"startMinute": 0
},
"network": {
"delegatedSubnetResourceId": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet",
"privateDnsZoneResourceId": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/myPrivateDnsZone",
"publicNetworkAccess": "Disabled"
},
"storage": {
"autoGrow": "Enabled",
"iops": 600,
"storageSizeGB": 128,
"storageRedundancy": "Zone"
},
"version": "8.0"
},
"sku": {
"name": "Standard_D2ds_v4",
"tier": "GeneralPurpose"
},
"tags": {
"Environment": "Production",
"Project": "MySQLMigration"
}
}
]
}
2 changes: 2 additions & 0 deletions tests/arm/checks/resource/test_MySQLPublicAccessDisabled.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ def test_summary(self):

passing_resources = {
"Microsoft.DBforMySQL/servers.pass",
"Microsoft.DBforMySQL/flexibleServers.pass2",
}
failing_resources = {
"Microsoft.DBforMySQL/servers.fail",
"Microsoft.DBforMySQL/flexibleServers.fail2",
}

passed_check_resources = {c.resource for c in report.passed_checks}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,36 @@ resource "azurerm_kubernetes_cluster_node_pool" "pass" {
}
}

resource "azurerm_kubernetes_cluster" "pass_new" {
name = "internal"
default_node_pool {
host_encryption_enabled = true
}
}

resource "azurerm_kubernetes_cluster_node_pool" "pass_new" {
name = "internal"
kubernetes_cluster_id = azurerm_kubernetes_cluster.example.id
vm_size = "Standard_DS2_v2"
node_count = 1
host_encryption_enabled = true
}


resource "azurerm_kubernetes_cluster" "fail_new" {
name = "internal"
default_node_pool {
host_encryption_enabled = false
}
}

resource "azurerm_kubernetes_cluster_node_pool" "fail_new" {
name = "internal"
kubernetes_cluster_id = azurerm_kubernetes_cluster.example.id
vm_size = "Standard_DS2_v2"
node_count = 1
host_encryption_enabled = false
}

resource "azurerm_kubernetes_cluster" "fail1" {
name = "internal"
Expand Down
Loading

0 comments on commit 7e0f74f

Please sign in to comment.