Pushing Secrets Into Azure Key Vault Directly From ARM Template


July 14, 2020

Azure Key Vault is a service that you can use to store application secrets and keys. You can store tokens, connection strings, certificates, API keys etc. in a Key Vault, and it provides a secured location with all usual safegaurds (encryption, access control etc.) that you would expect from such a solution.

In a previos post, I showed a simple technique to store the access credentials of a resource (e.g. a Service Bus) in an Azure Key Vault. In that post, I used “Write Secrets” task in an Azure Release pipeline to store the credentials.

Below I show a somewhat different way to do this and keep the pipeline simple by writing the secret directly from ARM template that creates the resource (i.e. Service Bus) in previous step.

Have a look at this repository for an example of this approach. I have used a YAML based pipeline to deploy various resources (Resource Group, Key Vault, Service Bus), and our objective is to store the Servie Bus endpoint information in the Key Vault (which is created one step before the Service Bus in the pipeline). The important bit here is last part of the template that deploys Service Bus.

{
    "type": "Microsoft.KeyVault/vaults/secrets",
    "name": "[concat(parameters('keyVaultName'), '/ServiceBusConnectionString')]",
    "apiVersion": "2019-09-01",
    "dependsOn": [
        "[parameters('serviceBusNamespaceName')]"
    ],
    "location": "[parameters('location')]", 
    "properties": {
        "value": "[listkeys(variables('authRuleResourceId'), variables('sbVersion')).primaryConnectionString]"
    }
}

This creates a new secret “ServiceBusConnectionString” in the Key Vault whose name is provided as a parameter to the template.

Note that to make this sample work, you will have to do a few things:

  1. Define pipeline variables azureResourceManagerConnectionName, and SubscriptionId that I have used in my YAML pipeline definition.
  2. Set objectId in accessPolicies in the parameters file for the template that deploys Key Vault. This objectId is supposed to be the id of the user in your Azure Active Direct tenant who will have access to this Key Vault. You will notice that in the keysPermission variable in our template, we have given list permissions to this user. You can use the Get-AzureRmADUser in Azure Cloud Shell to find an Id of a user that you want to give access to this Key Vault.

New release pipeline

This approach clearly makes the pipeline simpler, with no need to inject a script to parse template outputs to extract the secret (Service Bus endpoint in this case).

Conclusion

In this post we learned how to store credentials to access an Azure resource directly from an ARM template that deploys that resource, without parsing template output and using the “Writing Secrets” task in a Release pipeline.