Azure Policy – Audit disk encryption (SSE with CMK)
Microsoft recently launched a new service for disk encryption. This service builds upon the default storage encryption offered for Azure Managed Disks, by allowing customers to bring their own key (BYOK).
For most scenarios this is an improvement over Azure Disk Encryption, allowing for any type of OS and images, including custom images. Your experience may vary depending on regulatory requirements; my colleague discusses this topic in more detail in his blog post.
An issue with utilizing this new method for disk encryption, is that Azure Security Center isn’t aware of this recently launched feature. As a result, Security Center will report disks missing encryption if they’re encrypted using SSE with CMK.
Luckily, Security Center offers us to build our own custom Azure Policy Initiatives, and disable one or more of the built in Security Policies.
Azure Policy basically evaluates the Azure Resource Manager (ARM) templates and reports on or mitigates non-compliant values in the templates. For a custom policy, the goal is to write a logic which returns “true” if an ARM template is non-compliant. More details can be found in the official Microsoft Docs.
When SSE with CMK is enabled, the Virtual Machine resource will have its Managed Disks joined to a Disk Encryption Set. Thus, the custom Policy will check if all disks are joined to a Disk Encryption Set.
Because I prefer C-like syntax over JSON, I made a high-level pseudocode of this logic. Remember that an Azure Policy reports non-compliance if the logic returns true.
if (Virtual Machine) {
if (OSDisk is joined to Disk Encryption Set) {
foreach (DataDisk in DataDisks) {
if (DataDisk is joined to Disk Encryption Set) {
return false;
} else {
return true;
}
}
} else {
return true;
}
} else {
return false;
}
The actual custom Azure Policy JSON definition would look like this, utilizing the built in operators allOf (similar to AND/&&), anyOf (similar to OR/||) and count (similar to looping). The logical operators and counts are well documented in Microsoft Docs.
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Compute/virtualMachines"
},
{
"anyOf": [
{
"field": "Microsoft.Compute/virtualMachines/storageProfile.osDisk.managedDisk.diskEncryptionSet.id",
"exists": "false"
},
{
"count": {
"field": "Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*]",
"where": {
"allOf": [
{
"field": "Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].managedDisk.diskEncryptionSet.id",
"exists": "false"
}
]
}
},
"greater": 0
}
]
}
]
},
"then": {
"effect": "audit"
}