Contents

Encrypting disks on an Azure VM

Due to all the new privacy and data-protection rules like GDPR, I see a lot of companies looking at using disk encryption on their servers. In this case, a customer asked me to enable Azure Disk Encryption on their Azure VM’s.  Azure Disk Encryption encrypts the disks for your Azure VM at rest using the known Bitlocker technology. This is free -as in free beer. There is no extra charge for encrypting you disks in Azure. The crypthographic keys  are stored in Azure Key Vault. These cryptographic keys are used to encrypt and decrypt virtual disks attached to your VM. You retain control of these cryptographic keys and can audit their use through the Key Vault. An Azure Active Directory service principal is used for issuing these cryptographic keys as VMs are powered on and off.

Proces for encrypting a VM

The process for encrypting a VM is pretty straight forward:

  1. Create a cryptographic key in Azure Key Vault
  2. Configure the key to be usable for Azure Disk Encryption
  3. Create an Azure Active Directory service principal to be able to read the key
  4. Run the PowerShell command to encrypt your virtual disks, specifying the Azure Active Directory service principal and appropriate cryptographic key to be used
  5. The Azure AD service principal will request the required cryptographic key from Azure Key Vault
  6. The virtual disks are encrypting using the provided key

There are some requirements and limitations to keep in mind. Encryption can only be applied to VM’s in de standard tier and all resources (Key Vault, Storage Account and VM) should be in the same region. You can’t use Azure Disk Encryption for VM’s created in the classic deployment model and you can’t update the key on already encrypted VM’s.

So, let’s code!

In the following examples, we’ll use PowerShell to enable Azure Disk Encryption on the ‘myVm’ Virtual Machine in the ‘myResourceGroup’ resource group. All resources are based in the West Europe region. Of course, before you start, make sure that you are running the latest AzureRM module in Powershell.

First of all, we’ll set some variables and register the Azure Key Vault provider.

1
2
3
$rgName = "myResourceGroup"
$location = "West Europe"
Register-AzureRmResourceProvider -ProviderNamespace "Microsoft.KeyVault"

Next, we’ll create the key vault. I choose to use a specific key vault for storing my key, but you can use an existing key vault. Of course you can freely choose the name of your vault 🙂 Make sure to enable the key vault for disk encryption.

1
2
3
4
5
$keyVaultName = "KeyVaultName"
New-AzureRmKeyVault -Location $location `
    -ResourceGroupName $rgName `
    -VaultName $keyVaultName `
    -EnabledForDiskEncryption</pre>

Next, we’ll create a software-protected key in the vault to use with Azure Disk Encryption. This is the key that will actually be used for encrypting and decrypting your disks. Again, pick your own name for the key.

1
2
3
Add-AzureKeyVaultKey -VaultName $keyVaultName `
    -Name "myKey" `
    -Destination "Software"</pre>

When virtual disks are encrypted or decrypted, you specify an account to handle the authentication and exchanging of cryptographic keys from the key vault. This account, an Azure Active Directory service principal, allows the Azure platform to request the appropriate keys on behalf of the VM. We’ll create the service principal using the following code. When choosing your password, keep the Azure AD password policies and restrictions in mind.

1
2
3
4
5
6
7
$appName = "My App"
$securePassword = ConvertTo-SecureString -String "P@ssw0rd!" -AsPlainText -Force
$app = New-AzureRmADApplication -DisplayName $appName `
    -HomePage "https://myapp.contoso.com" `
    -IdentifierUris "https://contoso.com/myapp" `
    -Password $securePassword
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId

After creating the service principal, we have to set permissions on the key stored in the key vault to be read by the service principal.

1
2
3
4
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyvaultName `
    -ServicePrincipalName $app.ApplicationId `
    -PermissionsToKeys "WrapKey" `
    -PermissionsToSecrets "Set"

So, now all prerequisites are met to start encrypting disks. We kick off the encryption process on our VM

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$keyVault = Get-AzureRmKeyVault -VaultName $keyVaultName -ResourceGroupName $rgName;
$diskEncryptionKeyVaultUrl = $keyVault.VaultUri;
$keyVaultResourceId = $keyVault.ResourceId;
$keyEncryptionKeyUrl = (Get-AzureKeyVaultKey -VaultName $keyVaultName -Name myKey).Key.kid;

Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $rgName `
    -VMName "myVM" `
    -AadClientID $app.ApplicationId `
    -AadClientSecret (New-Object PSCredential "user",$securePassword).GetNetworkCredential().Password `
    -DiskEncryptionKeyVaultUrl $diskEncryptionKeyVaultUrl `
    -DiskEncryptionKeyVaultId $keyVaultResourceId `
    -KeyEncryptionKeyUrl $keyEncryptionKeyUrl `
    -KeyEncryptionKeyVaultId $keyVaultResourceId

You will be prompted to continue with the encryption. Once you accepted, the encryption process will be started and the VM will be restarted in the process.

Once the process has completed, you can check the status with the following command:

1
Get-AzureRmVmDiskEncryptionStatus  -ResourceGroupName $rgName -VMName "myVM"

The output will look something like this:

1
2
3
4
OsVolumeEncrypted          : Encrypted
DataVolumesEncrypted       : Encrypted
OsVolumeEncryptionSettings : Microsoft.Azure.Management.Compute.Models.DiskEncryptionSettings
ProgressMessage            : OsVolume: Encrypted, DataVolumes: Encrypted

That’s it! You just encrypted your disks using Azure Disk Encryption. Want to know more about this feature? Check the documentation.