Azure Key Vault: Step-by-step guide to perform simple backup and restore

By default, Azure Key Vault has multiple layers of redundancy within the region where it is hosted, and it is replicated to another region within the same geopolitical region. In the unlikely event of a region failure in Microsoft Azure, the remaining region will take over the Azure Key Vault after a few minutes, but the Azure Key Vault will be in read-only mode. All that high availability and resiliency of the service is built-in — as a customer, we don’t have to configure anything.

In some scenarios, the enterprise wants to control the disaster recovery capabilities and create a replica of a Key Vault to another region without relying on Microsoft Azure to perform the failover.

Azure Key Vault allows the process to export and import Keys and Secrets, as long as they are in the same subscription and same geography.

Defining a simple scenario

We are going to use a simple design. We will use (for now) our workstation or Azure Cloud Shell to export all Keys and Secrets from any given Azure Key Vault, and import those files extracted from the source Azure Key Vault to another Key Vault located in a different location.

Our design is simple and can be easily done running a couple of PowerShell cmdlets. However, we want to make sure that it is dynamic and for that reason, we will take advantage of Tags. We will associate two tags for each Azure Key Vault in production. They are going to be called KeyVaultBackupRole and KeyVaultBackupPair, where the first has the string Primary to represent all Azure Key Vault in the production environment, and the second tag will have the value of the Azure Key Vault that is the pair (the target for the export/import operation).

Having those two tags on all Azure Key Vaults that require a replica pair, we can start working on a script to evaluate those tags and perform actions to protect an entire subscription instead of a specific pair of Azure Key Vaults.

We can see a high-level design of our solution depicted in the image below. We can see that the Azure Key Vault in the Canada Central region has all the Keys and Secrets, and we have VMs and apps consuming that information. The Azure Key Vault is called APKVCAC and has two tags. In a second region of the same subscription, we have another Azure Key Vault that will receive all the Keys and Secrets from the original/source Azure Key Vault.

azure key vault

Understanding the backup and restore process

Let’s start getting down to the nitty-gritty and understand how to list, export, and import Keys and Secrets.

The basic cmdlets are Get-AzureRMKeyVault, which will list all Key Vaults of any given subscription; also Get-AzureKeyVaultSecret -VaultName <Vault-Name> to list all secrets and Get-AzureKeyVaultKey -VaultName <Vault-Name> to list Keys.

You may have noticed there are two separate cmdlets for Keys and Secrets. For example, to create a backup of a specific Key, we can use Backup-AzureKeyVaultKey -VaultName <Vault-Name> -Name <Key-Name>. The result will be a file on the local path (we can specify the output by using -OutputFile). If we want to protect a Secret, the only difference would be the cmdlet Backup-AzureKeyVaultSecret.

azure key vault

If we want to restore a specific Key or Secret, as long as we have the file it is just matter of running Restore-AzureKeyVaultKey -VaultName <vault-name> -InputFile <file> and the Key will be restored on the specified Vault Name. To perform the same activity with a Secret, just replace “Key” with “Secret” in the cmdlet.

azure key vault

Validating the replication based on our design

The first step in our script is to check all current Azure Key Vaults that support our Tags. Basically, we are going to query the entire subscription for Azure Key Vaults that have Primary value in their KeyVaultBackupRole, and have something associated to the KeyVaultBackupPair.

The following PowerShell script does exactly that.

Function ReportKVBackup{
Write-Output “Current Key Vaults properly configured for replication…”
$vKVaults = Get-AzureRmKeyVault | where-object { ($_.Tags.KeyVaultBackupRole -eq ‘Primary’) -and ($_.Tags.KeyVaultBackupPair -ne $null) }
write-Output $vKVaults.VaultName
Return $vKVaults

How do we test it? In this article, we are going to use Azure Cloud Shell. Basically, copy and paste the function in PowerShell and then execute it afterward. You can do the same when using PowerShell on your server/machine.

azure key vault

Azure Key Vault — backup process

The process to back up the Azure Key Vault is simple. We can create a function that receives the Primary Key Vault, and this function will generate a file for each Key and Secret on the designated Azure Key Vault.

In the code below, we can see that all Secrets and Keys are going to be stored in a subfolder within the C:\AzureKeyVaultSwap folder, and we are going to use a specific suffix for Keys (key.bkp) and Secrets (secret.bkp).

Function BKPKeyVault ($param_PrimaryKeyVault)
If ((Get-AzureRmKeyVault -VaultName $param_PrimaryKeyVault) -ne $null) {
If (test-path C:\AzureKeyVaultSwap\$param_PrimaryKeyVault) {Write-Output “Folder already exists”} Else { New-Item (“C:\AzureKeyVaultSwap\” + $param_PrimaryKeyVault) -ItemType Directory}
cd C:\AzureKeyVaultSwap\$param_PrimaryKeyVault
Get-AzureKeyVaultSecret -VaultName $param_PrimaryKeyVault | % { Backup-AzureKeyVaultSecret -VaultName $_.VaultName -Name $_.Name -OutputFile ($_.Name + “.secret.bkp”) -Confirm:$False -Force}
Get-AzureKeyVaultKey -VaultName $param_PrimaryKeyVault | % { Backup-AzureKeyVaultKey -VaultName $_.VaultName -Name $_.Name -OutputFile ($_.Name + “.key.bkp”) -Confirm:$False -Force}

Azure Key Vault — replication

After having the backup locally on the disk, our next step is to read those files and import them into the target Azure Key Vault.

Note: Unfortunately, there is no option to overwrite the values in the target, and that is the reason that we are removing the Keys and Secrets.

Function DRKeyVault($param_PrimaryKV,$param_SecondaryKV){
If (CheckKVReplication $param_PrimaryKV) {
Get-AzureKeyVaultSecret -VaultName $param_SecondaryKV | Remove-AzureKeyVaultSecret -confirm:$false -Force
Get-AzureKeyVaultKey -VaultName $param_SecondaryKV | Remove-AzureKeyVaultKey -Confirm:$False -Force
cd C:\AzureKeyVaultSwap\$param_PrimaryKV
$vSecretBKP = Get-Item *.secret.bkp
$vKeyBKP = Get-Item *.key.bkp
If ($vSecretBKP -ne $null) { $vSecretBKP | % { Restore-AzureKeyVaultSecret -VaultName $param_SecondaryKV -InputFile $_.Name } } Else { Write-Output “There are not Secrets to be transferred.” }
If ($vKeyBKP -ne $null) { $vKeyBKP | % { Restore-AzureKeyVaultKey -VaultName $param_SecondaryKV -InputFile $_.Name } } Else { Write-Output “There are not Keys to be transferred.” }
Write-Host ‘This’ $param_SecondaryKV ‘does not exist or the permission is not defined.’

Additional functions

We need to perform some validations to improve our current script. The function code below will return a True or False to check if the Azure Key Vault actually exists.

Function ValidateKVPair($param_KVPair){
If ((Get-AzureRmKeyVault $param_KVPair) -ne $null) {return $true} Else {return $False}

Another function to help our goal is the CheckKVReplication, where we check if Primary and Secondary Azure Key Vaults are valid. We should use this function before starting the process to backup and restore data.

Function CheckKVReplication($param_PrimaryKV){
$vPrimary_KeyVault = Get-AzureRMKeyVault $param_PrimaryKV -ErrorAction SilentlyContinue
If ($vPrimary_KeyVault -ne $null) {
$vSecondary_KeyVault = Get-AzureRMKeyVault $vPrimary_KeyVault.Tags.KeyVaultBackupPair -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
If ($vSecondary_KeyVault -ne $null) { return $True}Else{ return $False}
}Else{ write-Output “Sorry, however the Primary or Backup Pair Key Vault couldn’t be found at this time. Please review the current Azure Key Vault. “}

One last script that we are going to use is a simple house-cleaning rule that will remove the C:\AzureKeyVaultSwap folder and its subdirectories

Function SwapClean{
cd \
if (Test-Path C:\AzureKeyVaultSwap) {remove-item C:\AzureKeyVaultSwap -Force -Recurse }
New-Item C:\AzureKeyVaultSwap -ItemType directory
cd C:\AzureKeyVaultSwap

Wrapping it up

After creating a new PowerShell file (.ps1 extension) and adding all the functions listed, our final step is to add these two lines to get the script up and running.

Basically, that final code will create a list with all Azure Key Vault resources in the $vValidKVServers variable, and in the following line we will create a backup and restore of the data using the attributes that are coming from the tags.

$vVAlidKVServers = ReportKVBackup
$vValidKVServers | foreach { BKPKeyVault $_.VaultName;DRKeyVault $_.VaultName $_.Tags.KeyVaultBackupPair}

Keep in mind that we started small with a simple script to achieve our goal. By the end of this article I can see some improvements that can be done, as follows:

  • Use an automation account to create the protection of Azure Key Vaults
  • Use a specific account with only the required permissions to backup and restore
  • Improve the script to compare Keys and Secrets and only update the required ones. Right now, we dump the entire backup from Primary to the Secondary (by deleting the Keys and Secrets) since there is no overwrite option.

Featured image: Shutterstock

About The Author

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top