Using Azure Key Vault from Bicep

I have previously written a post on how to use Azure Key Vault with GitHub Actions, and this time I want to show you have to use Key Vault with Bicep deployments in Azure. The reason behind using Key Vault is to avoid having any passwords or secrets stored in templates. Using Key Vault, I can reference a secret that the deployment will look up at deployment time and not display in any log files. Another benefit of using Key Vaults is that the person who deploys the resources does not need to know the password for the resource but only the reference to the Key Vault. Deploying resources using Key Vaults dramatically increases the security and, at the same time, eases the deployments.

The code I used in the post is on my GitHub .


Azure Key Vault configuration
I need to configure Azure Key Vault to allow deployments to read the secrets/passwords stored in the Key Vault. The configuration is straightforward. I select my Key Vault, click on “Access policies,” and then mark “Azure Resource Manager for template deployment.”

I like to use parameters for all values that can change if I use the same template for multiple deployments. Below is the list of parameters I use for the virtual machine I will be deploying.

// VM parameters
param vmName string = 'vm-demo-001'
param vmSize string = 'Standard\_b2s'
param adminUsername string = 'LocalAdmin'
param vNetName string = 'vnet-demo-001' 
param vNetResourceGroup string = 'rg-bicep-demo-001'
param subnetName string = 'snet-demo-001'
var tags = {
  'Environment': 'Demo'
  'Owner': 'Martin'

To look up the password in Azure Key Vault, I also need to add a few parameters to the Key Vault I will be using.

param subscriptionId string = 'GUID'
param keyVaultResourceGroup string = 'rg-keyvault-001'
param keyVaultName string = 'kv-passwords-001'

Key Vault lookup
Before referencing the password in my Key Vault, I need to use Bicep’s “existing” feature. This feature will look up a resource in Azure, and I can then reference this resource and find the password I need. Below is my code to perform this lookup.

resource kv 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
  name: keyVaultName
  scope: resourceGroup(subscriptionId, keyVaultResourceGroup )

Deploy virtual machine
The last part is to deploy the virtual machine using a module. The deployment will perform the dynamic lookup of the password in Azure Key Vault and use it in the deployment. The module will deploy a virtual machine in an existing subnet, and it will be a workgroup machine. The code below shows how I call the module and reference the password.

module virtualMachine 'Modules/VirtualMachine.bicep' =  {
  name: vmName
  params: {
    adminUsername: adminUsername
    subnetName: subnetName
    VMName: vmName
    VMSize: vmSize
    adminPassword: kv.getSecret('vm-local-admin')
    vNetName: vNetName
    vNetResourceGroup: vNetResourceGroup
    tags: tags

  dependsOn: \[    

I can safely store my Bicep templates and modules with the deployment above without storing any passwords in my code. Using Azure Key Vault makes the deployment more secure while still being very simple to read and use.

I hope this post has been informative and if you have any questions, please reach out here on the website or Twitter.