This check flags Azure VM data disks that lack encryption at rest, leaving sensitive data readable if the underlying storage is accessed directly. Enable Azure Disk Encryption or confirm platform-managed/customer-managed keys are applied to every data disk.
Azure managed disks come with platform-managed encryption by default, but that default does not cover every scenario, and it is easy to end up with data disks that are not encrypted the way your compliance baseline requires. The VM Data Disk Not Encrypted check looks at the data disks attached to your Azure VMs and reports any that are missing encryption at rest.
If you handle regulated data, run workloads under PCI DSS, HIPAA, or SOC 2, or simply want defense in depth, unencrypted data disks are a finding you want to clear quickly.
What this check detects
The vm_datadiskencryption check inspects each Azure VM in scope and evaluates the encryption status of its attached data disks. A disk is flagged when it has no encryption configuration applied, meaning the data written to that volume is stored without an encryption layer you control or verify.
There are a few distinct encryption mechanisms in play on Azure, and the check exists because they are not interchangeable:
- Server-Side Encryption (SSE) with platform-managed keys (PMK) — enabled by default on managed disks, transparent to the VM.
- Server-Side Encryption with customer-managed keys (CMK) — uses a key you store in Azure Key Vault, giving you control over rotation and revocation.
- Azure Disk Encryption (ADE) — uses BitLocker (Windows) or DM-Crypt (Linux) inside the guest OS to encrypt the volume.
- Encryption at host — encrypts data on the host machine itself, including temp disks and disk caches.
Note: Managed disks are encrypted with platform-managed keys by default, but unmanaged disks (page blobs in a storage account) and disks created under certain legacy or custom configurations may not be. This check catches the gaps where no enforced encryption is present, or where your policy requires CMK or ADE that has not been applied.
Why it matters
Encryption at rest protects against a specific class of threats: someone reading your data without going through the VM's authentication and access controls. The most common scenarios are not glamorous, but they are real.
Data exposure through disk export or snapshot
Disk snapshots and exports are easy to create and easy to forget about. If an attacker gains permission to export a disk or copy a snapshot, an unencrypted disk hands them the full filesystem in plaintext. With encryption tied to a key vault you control, the exported bytes are useless without access to the key.
Compliance and audit failures
Most frameworks treat encryption at rest as a baseline control. A single unencrypted data disk holding cardholder data or PHI can turn a passing audit into a finding. Auditors increasingly ask for customer-managed keys specifically, because platform-managed keys do not give the customer control over key lifecycle.
Warning: Platform-managed encryption satisfies the technical requirement of "encrypted at rest" but does not satisfy controls that demand customer control over keys. If your obligation is CMK, a disk using only the default PMK will still fail an audit even though it is technically encrypted.
Lost or decommissioned hardware
This is the original reason encryption at rest exists. Azure handles physical media destruction, but encryption removes any residual risk that recoverable data lingers on a drive that leaves a datacenter.
How to fix it
The right fix depends on which encryption model you need. Below are the three common paths. Start by checking what is currently applied.
1. Inspect the current encryption status
az disk show \
--resource-group myResourceGroup \
--name myDataDisk \
--query "{name:name, encryptionType:encryption.type, diskEncryptionSetId:encryption.diskEncryptionSetId}" \
--output table
An encryptionType of EncryptionAtRestWithPlatformKey means default PMK. EncryptionAtRestWithCustomerKey means CMK is applied.
2. Apply customer-managed keys (CMK)
CMK is the most common requirement. First create a Key Vault and a disk encryption set, then point the disk at it.
# Create a Key Vault with purge protection (required for disk encryption)
az keyvault create \
--name myDiskKeyVault \
--resource-group myResourceGroup \
--location eastus \
--enable-purge-protection true
# Create a key
az keyvault key create \
--vault-name myDiskKeyVault \
--name myDiskKey \
--protection software
# Create a disk encryption set referencing the key
KEY_URL=$(az keyvault key show --vault-name myDiskKeyVault --name myDiskKey --query "key.kid" -o tsv)
az disk-encryption-set create \
--resource-group myResourceGroup \
--name myDiskEncryptionSet \
--key-url "$KEY_URL" \
--source-vault myDiskKeyVault
# Grant the disk encryption set's identity access to the vault
DES_ID=$(az disk-encryption-set show --name myDiskEncryptionSet --resource-group myResourceGroup --query "identity.principalId" -o tsv)
az keyvault set-policy \
--name myDiskKeyVault \
--object-id "$DES_ID" \
--key-permissions get wrapKey unwrapKey
Danger: Changing encryption on an attached disk requires the disk to be detached, and the VM must be deallocated. Do not run the next command against a production VM during business hours. Schedule a maintenance window and confirm you have a recent snapshot first.
# Deallocate the VM first
az vm deallocate --resource-group myResourceGroup --name myVM
# Apply the disk encryption set to the data disk
DES_RESOURCE_ID=$(az disk-encryption-set show --name myDiskEncryptionSet --resource-group myResourceGroup --query "id" -o tsv)
az disk update \
--resource-group myResourceGroup \
--name myDataDisk \
--disk-encryption-set "$DES_RESOURCE_ID" \
--encryption-type EncryptionAtRestWithCustomerKey
# Start the VM again
az vm start --resource-group myResourceGroup --name myVM
3. Enable encryption at host
Encryption at host covers temp disks and caches that other methods miss, and it does not require deallocating for the host-level setting on supported VM sizes. The feature must be registered on the subscription first.
# Register the feature (one time per subscription)
az feature register --namespace Microsoft.Compute --name EncryptionAtHost
az provider register --namespace Microsoft.Compute
# Enable on the VM (VM must be deallocated)
az vm update \
--resource-group myResourceGroup \
--name myVM \
--set securityProfile.encryptionAtHost=true
4. Enable Azure Disk Encryption (ADE) for guest-level encryption
If you need in-guest encryption with BitLocker or DM-Crypt, enable ADE and target all volumes.
az vm encryption enable \
--resource-group myResourceGroup \
--name myVM \
--disk-encryption-keyvault myDiskKeyVault \
--volume-type ALL
Tip: For new disks, set encryption at creation time so you never have to deallocate later. Pass --encryption-type EncryptionAtRestWithCustomerKey and --disk-encryption-set on az disk create, or bake it into your VM templates so every disk is born encrypted.
How to prevent it from happening again
Manual remediation does not scale. The durable fix is to make encryption the default in your provisioning pipeline and block anything that drifts.
Enforce with Azure Policy
Azure ships built-in policy definitions that audit or deny unencrypted disks. Assign the policy that requires customer-managed keys so new disks cannot be created without one.
# Assign the built-in policy requiring CMK on managed disks
az policy assignment create \
--name require-cmk-disks \
--display-name "Managed disks must use customer-managed keys" \
--policy "ca91455f-eace-4f96-be59-e6e2c35b4816" \
--scope "/subscriptions/"
Note: Use Audit effect first to measure your exposure, then move to Deny once existing disks are remediated. Flipping straight to Deny can block legitimate deployments and create noise.
Bake encryption into your IaC
Define encrypted-by-default disks in Terraform so reviewers see the configuration in every pull request:
resource "azurerm_managed_disk" "data" {
name = "app-data-disk"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
storage_account_type = "Premium_LRS"
create_option = "Empty"
disk_size_gb = 256
disk_encryption_set_id = azurerm_disk_encryption_set.main.id
}
Add a CI/CD gate
Run a static analysis tool against your IaC before it merges. Tools like Checkov or tfsec catch a missing disk_encryption_set_id at PR time, long before the disk exists.
# Fail the build if any disk lacks encryption configuration
checkov -d ./infra --check CKV_AZURE_93
Best practices
- Default to customer-managed keys. CMK gives you key rotation, revocation, and an audit trail that platform-managed keys do not. If you can revoke a key, you can render exported data unreadable in an incident.
- Turn on encryption at host alongside CMK. It closes the gap on temp disks and caches that disk-level encryption leaves exposed.
- Enable purge protection and soft delete on the Key Vault. Losing a disk encryption key means losing the data on the disk. Purge protection prevents accidental or malicious key deletion.
- Rotate keys on a schedule. Configure automatic key rotation in Key Vault so compliance windows are met without manual work.
- Separate key management from VM management. The team that operates VMs should not necessarily hold the keys. Use RBAC to keep key administration with your security team.
- Scan continuously, not just at deploy time. Disks get attached, snapshots get copied, and configurations drift. Continuous checks like this one catch what slipped through the pipeline.
Tip: Pair this check with a snapshot-encryption check. A perfectly encrypted disk can still leak through an unencrypted snapshot, so treat both as part of the same control.
Clearing this finding is rarely just about flipping one switch. The lasting win comes from making encrypted disks the only kind your environment can produce, then verifying that promise continuously.

