How to create an Azure Keyvault secret and copy an access key using an ARM template

Projects hosted in Azure should store passwords and other sensitive information in a Keyvault. It’s a good practice that makes an application safer because it prevents the leakage of the information in case of unauthorized access to the server.

Another good practice is deploy using Infrastructure as Code (IaC) because it removes manual processes that requires a lot of time, and prevents human errors that could make the deploy to fail.

In this post you will learn how to use an ARM template to create a Keyvault secret and to store a key from an Azure Resource (in this example is a Storage Account) as the secret value. In this case you will use an ARM template, but there are other ways to do it like Terraform templates or Azure CLI (recommendation: use CLI only for legacy projects that can’t use IaC)

You can download the complete example from Github: Branyac/Azure-ARMTemplate-CreateStorageKeyvaultAndStoreKeyInSecret.json. The example also creates an Azure Storage Account and a Keyvault.

This is the section of the template that creates the secret and sets the value:

{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2021-04-01-preview",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
],
"name": "[format('{0}/{1}-key', parameters('keyVaultName'), parameters('storageAccountName'))]",
"properties": {
"value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-06-01').keys[parameters('storageKeyNumber')].value]"
}
}

An this is how it works:

  • First the property ‘dependsOn’ checks that keyvault and storage account exists*.
  • After that, the property ‘name’ sets the name of the Keyvault Secret where the key will be stored. In this case the name of the secret will be the name of the Azure Storage account ended in ‘-key’.
  • In the section “properties” the property “value” references* the Azure Storage account of the template and reads the key.
  • The parameter ‘storageKeyNumber’ sets the number of the key that will be stored as the keyvault secret value, use 0 to copy the first key or 1 to copy the second key.

Take in count:

  • If there is a Keyvault secret with the same name the value of that secret will be replaced by the value of this template. The old value will not be deleted and will remain in the version history of the secret.
  • * If you need to access an Azure resource that is not in the template or is in a different Azure subscription, follow these instructions: Resource functions for ARM templates