Skip to content

Commit

Permalink
feat(general): TF and ARM - Ensure that Databricks Workspaces enable… (
Browse files Browse the repository at this point in the history
…#6313)

feat(general) - TF and ARM - Ensure that Databricks Workspaces enables customer-managed key for root DBFS encryption

Co-authored-by: tlevi <[email protected]>
  • Loading branch information
MrTomerLevi and tlevi authored May 23, 2024
1 parent 7461974 commit a6b9e98
Show file tree
Hide file tree
Showing 9 changed files with 349 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import annotations

from typing import Any

from checkov.common.models.enums import CheckResult, CheckCategories
from checkov.arm.base_resource_check import BaseResourceCheck
from checkov.common.util.data_structures_utils import find_in_dict


class DatabricksWorkspaceDBFSRootEncryptedWithCustomerManagedKey(BaseResourceCheck):
def __init__(self) -> None:
# https://learn.microsoft.com/en-us/azure/templates/microsoft.databricks/workspaces?pivots=deployment-language-arm-template#workspaceencryptionparameter-1
name = "Ensure that Databricks Workspaces enables customer-managed key for root DBFS encryption"
id = "CKV2_AZURE_48"
supported_resources = ("Microsoft.Databricks/workspaces",)
categories = (CheckCategories.ENCRYPTION,)
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)

def scan_resource_conf(self, conf: dict[str, Any]) -> CheckResult:
parameters = conf.get("properties", {}).get("parameters")
prepare_encryption = find_in_dict(input_dict=parameters, key_path="prepareEncryption/value")
if not prepare_encryption or str(prepare_encryption).lower() != "true":
return CheckResult.FAILED

encryption_settings = find_in_dict(input_dict=parameters, key_path="encryption/value")
if not encryption_settings:
return CheckResult.FAILED

return CheckResult.PASSED


check = DatabricksWorkspaceDBFSRootEncryptedWithCustomerManagedKey()
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
metadata:
id: "CKV2_AZURE_48"
name: "Ensure that Databricks Workspaces enables customer-managed key for root DBFS encryption"
category: "ENCRYPTION"
definition:
or:
- and:
- cond_type: filter
attribute: resource_type
operator: within
value:
- azurerm_databricks_workspace
- resource_types:
- azurerm_databricks_workspace
operator: not_equals
cond_type: attribute
attribute: sku
value: "premium"
- and:
- cond_type: filter
attribute: resource_type
operator: within
value:
- azurerm_databricks_workspace
- resource_types:
- azurerm_databricks_workspace
operator: equals
cond_type: attribute
attribute: sku
value: "premium"
- resource_types:
- azurerm_databricks_workspace
operator: equals
cond_type: attribute
attribute: customer_managed_key_enabled
value: true
- resource_types:
- azurerm_databricks_workspace
connected_resource_types:
- azurerm_databricks_workspace_root_dbfs_customer_managed_key
operator: exists
cond_type: connection

# Root DBFS encryption is only valid if the Databricks Workspace sku is set to 'premium'.
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/databricks_workspace#customer_managed_key_enabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"managedResourceGroupName": {
"type": "string"
},
"workspaceName": {
"type": "string",
"metadata": {
"description": "The name of the Azure Databricks workspace to create."
}
},
"location": {
"type": "string",
"metadata": {
"description": "Location for all resources."
}
},
"pricingTier": {
"type": "string",
"allowedValues": [
"standard",
"premium"
],
"metadata": {
"description": "The pricing tier of workspace."
}
},
"keyVaultName": {
"type": "string",
"metadata": {
"description": "The Azure Key Vault name."
}
},
"keyName": {
"type": "string",
"metadata": {
"description": "The Azure Key Vault encryption key name."
}
},
"disablePublicIp": {
"type": "bool",
"metadata": {
"description": "Specifies whether to deploy Azure Databricks workspace with Secure Cluster Connectivity (No Public IP) enabled or not"
}
}
},
"resources": [
{
"type": "Microsoft.Databricks/workspaces",
"apiVersion": "2023-02-01",
"name": "[parameters('workspaceName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('pricingTier')]"
},
"properties": {
"managedResourceGroupId": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('managedResourceGroupName'))]",
"parameters": {
"enableNoPublicIp": {
"value": "[parameters('disablePublicIp')]"
}
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"managedResourceGroupName": {
"type": "string"
},
"workspaceName": {
"type": "string",
"metadata": {
"description": "The name of the Azure Databricks workspace to create."
}
},
"location": {
"type": "string",
"metadata": {
"description": "Location for all resources."
}
},
"pricingTier": {
"type": "string",
"allowedValues": [
"standard",
"premium"
],
"metadata": {
"description": "The pricing tier of workspace."
}
},
"keyVaultName": {
"type": "string",
"metadata": {
"description": "The Azure Key Vault name."
}
},
"keyName": {
"type": "string",
"metadata": {
"description": "The Azure Key Vault encryption key name."
}
},
"disablePublicIp": {
"type": "bool",
"metadata": {
"description": "Specifies whether to deploy Azure Databricks workspace with Secure Cluster Connectivity (No Public IP) enabled or not"
}
}
},
"resources": [
{
"type": "Microsoft.Databricks/workspaces",
"apiVersion": "2023-02-01",
"name": "[parameters('workspaceName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('pricingTier')]"
},
"properties": {
"managedResourceGroupId": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('managedResourceGroupName'))]",
"parameters": {
"prepareEncryption": {
"value": false
},
"enableNoPublicIp": {
"value": "[parameters('disablePublicIp')]"
}
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"managedResourceGroupName": {
"type": "string"
},
"workspaceName": {
"type": "string",
"metadata": {
"description": "The name of the Azure Databricks workspace to create."
}
},
"location": {
"type": "string",
"metadata": {
"description": "Location for all resources."
}
},
"pricingTier": {
"type": "string",
"allowedValues": [
"standard",
"premium"
],
"metadata": {
"description": "The pricing tier of workspace."
}
},
"keyVaultName": {
"type": "string",
"metadata": {
"description": "The Azure Key Vault name."
}
},
"keyName": {
"type": "string",
"metadata": {
"description": "The Azure Key Vault encryption key name."
}
},
"disablePublicIp": {
"type": "bool",
"metadata": {
"description": "Specifies whether to deploy Azure Databricks workspace with Secure Cluster Connectivity (No Public IP) enabled or not"
}
}
},
"resources": [
{
"type": "Microsoft.Databricks/workspaces",
"apiVersion": "2023-02-01",
"name": "[parameters('workspaceName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('pricingTier')]"
},
"properties": {
"managedResourceGroupId": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('managedResourceGroupName'))]",
"parameters": {
"prepareEncryption": {
"value": true
},
"encryption": {
"value": {
"keySource": "Microsoft.Keyvault",
"keyvaulturi": "[uri(format('https://{0}{1}', parameters('keyVaultName'), environment().suffixes.keyvaultDns), '/')]",
"KeyName": "[parameters('keyName')]"
}
},
"enableNoPublicIp": {
"value": "[parameters('disablePublicIp')]"
}
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os
import unittest

from checkov.arm.checks.resource.DatabricksWorkspaceDBFSRootEncryptedWithCustomerManagedKey import check
from checkov.arm.runner import Runner
from checkov.runner_filter import RunnerFilter


class TestDatabricksWorkspaceDBFSRootEncryptedWithCustomerManagedKey(unittest.TestCase):

def test_summary(self):
runner = Runner()
current_dir = os.path.dirname(os.path.realpath(__file__))

test_files_dir = current_dir + "/example_DatabricksWorkspaceDBFSRootEncryptedWithCustomerManagedKey"
report = runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter(checks=[check.id]))
summary = report.get_summary()

self.assertEqual(summary['passed'], 1)
self.assertEqual(summary['failed'], 2)
self.assertEqual(summary['skipped'], 0)
self.assertEqual(summary['parsing_errors'], 0)


if __name__ == '__main__':
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pass:
- "azurerm_databricks_workspace.databricks_workspace_good"
fail:
- "azurerm_databricks_workspace.databricks_workspace_bad"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
resource "azurerm_databricks_workspace" "databricks_workspace_bad" {
name = "example"
location = "location"
resource_group_name = "group"
sku = "premium"
managed_resource_group_name = "example"
}


resource "azurerm_databricks_workspace" "databricks_workspace_good" {
name = "example"
location = "location"
resource_group_name = "group"
sku = "premium"
managed_resource_group_name = "example"
customer_managed_key_enabled = true
}

resource "azurerm_databricks_workspace_root_dbfs_customer_managed_key" "databricks_workspace_good" {
workspace_id = azurerm_databricks_workspace.databricks_workspace_good.id
key_vault_key_id = "123456"
}
3 changes: 3 additions & 0 deletions tests/terraform/graph/checks/test_yaml_policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ def setUp(self) -> None:
warnings.filterwarnings("ignore", category=ResourceWarning)
warnings.filterwarnings("ignore", category=DeprecationWarning)

def test_DatabricksWorkspaceDBFSRootCustomerManagedKey(self):
self.go("DatabricksWorkspaceDBFSRootEncryptedWithCustomerManagedKey")

def test_KmsKeyPolicyIsDefined(self):
self.go("KmsKeyPolicyIsDefined")

Expand Down

0 comments on commit a6b9e98

Please sign in to comment.