6 min read

Backup & Restore Key Vault Secrets via Logic Apps

Justin Yoo

There are always chances to backup and restore an Azure Key Vault instance. At this time of writing, Key Vault doesn't support the bulk back-up of the whole keys/secrets/certificates in an instance, but only supports back-up individual keys/secrets/certificates. Generally speaking, one Key Vault instance stores multiple secrets. The individual back-up feature doesn't fit this case. With Azure Event Grid, we can monitor status change of each Key Vault secret. However, it's good for backup, not for restore. In this post, I'm going to use the Azure Logic App workflow and the Managed Identity feature, to backup and restore secrets stored in an Azure Key Vault instance.

ARM Templates used in this post can be found at this GitHub repository.

Workflow to Backup Secrets from Key Vault

Let's assume that a Key Vault instance to run back-up stores four secrets. Of course, in the real-world scenario, there will be a lot more than four, but as an example, the four secrets would be sufficient. As each secret keeps the change history, the Key Vault back-up/restore includes all the histories.

Let's create the workflow to back-up those secrets. First of all, we need a Logic App instance. Once it's created, activate the Managed Identity feature so that Key Vault instance can allow direct access to the Logic App instance.

After enabling the Managed Identity feature on the Logic App instance, it generates the ObjectId value. Use this value to apply the access policy onto the Logic App instance.

The first part of the workflow is the HTTP trigger. For now, we use the HTTP trigger, but if you want to run this workflow regularly, then change the trigger to Scheduler.

Let's add other actions to complete the workflow. As we're aiming to back-up all secrets in the Key Vault instance, each back-up secret should be added to an array object. Add the InitializeVariable action, give it the name of BackupItems and assign its data type to Array.

The following action calls a RESTful API for Key Vault. There is a connector for Key Vault, but it doesn't support back-up and restore. Therefore, it would be a good idea to call the endpoint through the HTTP action directly. If you want to know more about this, please have a look at my other post, Accessing Key Vault from Logic App with Managed Identity.

  • URI: The endpoint to fetch the list of secrets from Key Vault. Generally it looks like https://[KEY_VAULT_NAME].vault.azure.net/secrets.
  • Queries: API version to call the API. The latest version we're using here is 7.0.
  • Authentication: Select Managed Identity.
  • Audience: Enter https://vault.azure.net.

The action above gets the list of secrets from Key Vault as an array. Therefore, loop the array with the ForEach action.

Within the loop, add another HTTP action to run back-up on each secret item. The result of the action is the response of the back-up.

The result of the action is added to the variable initially declared at the beginning.

Now, we got all the secrets backed up and added to the array. Let's run the following action to confirm the array.

Finally, store the array into the Azure Blob Storage instance.

All the secrets from the Key Vault have now been stored to Azure Blob Storage.

So far, we've discussed the way to back-up Key Vault secrets to Azure Blob Storage in bulk.

Workflow to Restore Secrets to Azure Key Vault

As we built the back-up workflow above, let's have a look at the restore workflow, which is not much different from the previous one. The main difference of restoration workflow is to consider how to take the latest back-up file from the list. I'm not going to discuss it further because the selection process has already been explained in my previous post.

Like the Logic App instance for the back-up, once the instance is provisioned, the first thing would be to activate the Managed Identity feature. The second thing to do is to connect Integration Account with the Logic App instance. Only after the Integration Account connection, we can use the Inline JavaScript Code Action.

Let's add the workflow. First of all, add the HTTP Trigger.

The first action would be to fetch the list of back-up files from Azure Blob Storage, which is an array.

Then, this is the most crucial part of this workflow. From the back-up file list as an array, we need to pick up the latest one via the [Inline JavaScript Code] action. Here's the code snippet:

"use strict";
// Assign the array value from the output of the previous action, `List Backups`.
var items = workflowContext.actions.List_Backups.outputs.body.value;
var sorted = items.sort(function (a, b) {
var dateA = a.Name.replace('.json', '');
var dateB = b.Name.replace('.json', '');
if (dateA > dateB) {
return -1;
}
if (dateA < dateB) {
return 1;
}
return 0;
});
var result = sorted[0].Path;
// Returns the result as output.
return result;
view raw sort-action.js hosted with ❤ by GitHub

How it works can be found at my previous post.

Once we get the latest back-up file, download the content from Azure Blob Storage through this action.

The downloaded content is encoded in base-64. Therefore, we should decode and convert it to a JSON object for the next action.

The converted JSON is an array of all secrets. Add the ForEach loop action for the array.

Inside the loop, add another HTTP action with the following details:

  • URI: The URI to restore each secret item. It's generally https://[KEY_VAULT_NAME].vault.azure.net/secrets/restore.
  • Queries: API version for request. The latest version for this call is 7.0.
  • Authentication: Select Managed Identity.
  • Audience: Enter https://vault.azure.net.

After restoring all the secrets, run the following action against the new Key Vault instance to fetch the restored secrets.

Now, we can confirm the secrets are all restored from Azure Blob Storage.

So far, we've built a Logic App workflow to restore secrets from the back-up file stored in Azure Blob Storage.

ARM Templates for Provisioning

If you want to quickly have a look at the complete resources used for this practice, there's an easy way. Download ARM templates from the GitHub repository and run them in the following order.

  1. Integration Account: integrationAccount.json
  2. Azure Storage Account: storageAccount.json
  3. Azure Blob Storage Connector: connection.azureblob.json
  4. Azure Logic App for Backup: logicApp.json
  5. Azure Logic App for Restore: logicApp.json
  6. Azure Key Vault for Backup: keyVault.json
  7. Azure Key Vault for Restore: keyVault.json

Use the following PowerShell script for the ARM template deployment.

New-AzResourceGroupDeployment `
-Name "[DEPLOYMENT_NAME]" `
-ResourceGroupName "[RESOURCE_GROUP_NAME]"
-TemplateFile "integrationAccount.json" `
-TemplateParameterFile "integrationAccount.parameters.json" `
-Verbose

Once everything is provisioned, there's one more step. The Logic App instances are blank. Therefore, run the following PowerShell script again to add the workflow for both back-up and restore.

  1. Backup: backup.json
  2. Restore: restore.json
Set-LogicAppWorkflow.ps1 `
-ResourceGroupName "[RESOURCE_GROUP_NAME]" `
-LogicAppName "[LOGIC_APP_NAME]" `
-DefinitionFile "[WORKFLOW_DEFINITION_FILE]" `
-ParameterFile "[WORKFLOW_DEFINITION_PARAMETER_FILE]"

So far, we've walked through how we can back-up secrets from an Azure Key Vault instance and restore them into another Key Vault instance, through a Logic App workflow. As it's not that complex, it would be really great if you have a run with your free Azure account for your own time for practice.