Updating the Azure VM Encryption Certs

This is an update to a previous blog post regarding BitLocker encryption of your Azure VMs using certificates and Azure KeyVault. That article can be found here.

The next obvious question is: Great, what happens when my certificate expires? Well, you need to update it BEFORE that happens, so I suggest keeping tabs on them. The process to update them is pretty straightforward and consists of updating the Azure AD Application Service Principal Credential, the VM and the Extension. This does NOT cause a re-bitlockering which is good!

First, make sure you are logged in with both AzureRM and MSOL:

ipmo msoline
$msolcred = get-credential
connect-msolservice -credential $msolcred
add-azurermaccount -subscriptionid <yoursubidhere>

Next, we need to get the current setup:

Get the VM:
$RGName = 'rg-azurekvtesting'
$vm = get-azurermvm -ResourceGroupName $rgname
$vmName = $vm.Name

Get the Azure AD Application and the service principal
$serviceprincipal = get-azurermadserviceprincipal -ServicePrincipalName "http://thisneedstobegloballyunique"

An interesting note here is that you can't get the Service Principal by smart things like an ID, you have to use that Globally Unique URI that was part of your initial setup last time.

Get the Vault:
$KeyVaultName = 'kv-azurekvtesting'
$keyvault = get-azurermkeyvault -vaultname $keyvaultname
$diskencryptionvaulturl = $keyvault.vaulturi
$keyvaultresourceid = $keyvault.resourceid

Get the NEW cert and process it just like last time:
$fileName = "C:\adifferentcert.pfx"
$cert = Get-PfxCertificate -FilePath $fileName
$bincert = $cert.getrawcertdata()
$credvalue = [system.convert]::ToBase64String($bincert)
$thumbprint = $cert.thumbprint
$plaintextPassword = '!password1'
$mypwd = ConvertTo-SecureString -String $plaintextPassword -Force –AsPlainText
$fileContentBytes = get-content $fileName -Encoding Byte
$fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes)
$jsonObject = @"
"data": "$filecontentencoded",
"dataType" :"pfx",
"password": "$plaintextPassword"
$jsonObjectBytes = [System.Text.Encoding]::UTF8.GetBytes($jsonObject)
$jsonEncoded = [System.Convert]::ToBase64String($jsonObjectBytes)

Now, update the AAD application by simply creating a new SP Cred:

New-MsolServicePrincipalCredential -ServicePrincipalName $serviceprincipal.ServicePrincipalName -Type asymmetric -Value $credValue

Now, update KeyVault with the new certificate:
$kekname = 'keyencryptionkey'
$kek = get-azurekeyvaultkey -vaultname $keyvaultname -name $kekname
$KeyEncryptionKeyUrl = $kek.key.kid
$secret = ConvertTo-SecureString -String $jsonEncoded -AsPlainText –Force
Set-AzureKeyVaultSecret -VaultName $keyVaultName -Name $vmName -SecretValue $secret
$encryptionCertURI = (get-azurekeyvaultsecret -vaultname $keyVaultName -Name $vmname).Id

Now, update the VM (put the new cert into the VM):
add-azurermvmsecret -VM $vm -sourcevaultid $keyvault.resourceid -certificatestore 'My' -CertificateURL $encryptionCertURI
update-azurermvm -resourcegroupname $rgname -vm $vm
(Takes a bit)

Last step, update the Extension with all the new bits and bites:
Set-AzureRmVMDiskEncryptionExtension -ResourceGroupName $rgname -VMName $vmname -AadClientID $aadClientID -AadClientCertThumbprint $Thumbprint -DiskEncryptionKeyVaultUrl $diskencryptionvaulturl -DiskEncryptionKeyVaultId $keyvault.resourceid -KeyEncryptionKeyUrl $keyEncryptionKeyUrl -KeyEncryptionKeyVaultId $keyvault.resourceid

Boom! Next time, we'll talk more about best practices and how to keep an eye on things.