Bicep - Deploying keys with rotation policies in Azure Key Vault
Hi! This week, we’re talking about security, specifically how to use automatic key rotation in Azure Key Vault.
In case you didn’t know, Azure Key Vault’s automated key rotation improves security by creating new key versions at set intervals and sending expiration alerts via Event Grid. This not only enhances security measures but also aligns with compliance mandates, reducing potential risks of data breaches.
In this post, I’ll use Bicep templates to efficiently install and configure these key rotation policies in Azure Key Vault. Let us begin.
Prerequisites #
Before you start, you’ll need the following to deploy and manage resources with Bicep:
- You need Azure CLI version 2.20.0 or later to deploy Bicep files on your local machine.
- A text editor or IDE of your choice (Visual Studio Code with Bicep extension is my recommendation)
Create the Bicep file #
The first step in deploying a Bicep template is to create the Bicep file that defines your resources. Create a new file named keyRotationPolicy.bicep. This file will contain the code needed to define and configure the deployment of your resources.
@description('Specifies the name of the key vault to be created.')
param vaultName string
@description('Specifies the name of the key to be created within the vault.')
param keyName string
@description('Specifies the size of the RSA key.')
@allowed([
2048
3072
4096
])
param rsaKeySize int
@description('Indicates if the key is active or not.')
param isKeyEnabled bool = true
@description('Specifies the duration after which the key should be rotated.')
@allowed([
'P6M'
'P1Y'
'P2Y'
])
param rotationTimeAfterCreate string
@description('Specifies the expiration duration for the new key version.')
@allowed([
'P7M'
'P13M'
'P25M'
])
param expiryTime string
@description('Duration before key expiration to trigger a notification.')
@allowed([
'P15D'
'P30D'
'P45D'
])
param notifyTimeBeforeExpiry string
@description('The tags to be associated with the resources.')
param tags object = {
bicep: 'true'
environment: 'jorgebernhardt.com'
}
resource keyVaultKey 'Microsoft.KeyVault/vaults/keys@2023-02-01' = {
name: '${vaultName}/${keyName}'
tags: tags
properties: {
kty: 'RSA'
keySize: rsaKeySize
rotationPolicy: {
lifetimeActions: [
{
trigger: {
timeAfterCreate: rotationTimeAfterCreate
}
action: {
type: 'rotate'
}
}
{
trigger: {
timeBeforeExpiry: notifyTimeBeforeExpiry
}
action: {
type: 'notify'
}
}
]
attributes: {
expiryTime: expiryTime
}
}
attributes:{
enabled: isKeyEnabled
}
}
}
output keyVaultKeyID string = keyVaultKey.id
output keyVaultKeyRotationPolicy object = keyVaultKey.properties.rotationPolicy
output keyVaultKeyExpirationTime string = keyVaultKey.properties.rotationPolicy.attributes.expiryTime
Important: While this Bicep template makes it easy to initially create a key in Azure Key Vault and its associated rotation policy, it’s essential to understand that it can’t be changed once the key is generated. However, the rotation policy is still configurable after creation.
Deployment scope #
You can target your deployment to a resource group, subscription, management group, or tenant. In this case, when creating keys into an Azure Key vault, the scope where the resource should be deployed is a resource group.
You can use an existing Azure Key vault or create a new one. Check out this link if you want to know how to create a key vault using Azure CLI.
Deploy the Bicep template using the Azure CLI #
Once your Bicep template is prepared, and you’ve selected your desired scope, you can proceed to deploy the template through the Azure CLI. To do so, execute the following commands.
Parameters #
Personalization is key to making your template reusable. With the parameters, you can easily tailor the template to your specific needs. You can use either inline parameters or a parameter file to pass parameter values. In my case, I will use a file to pass the parameters; here is an example.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vaultName": {
"value": "KV-DEMO"
},
"keyName": {
"value": "DemoRSAKey"
},
"isKeyEnabled": {
"value": true
},
"rotationTimeAfterCreate": {
"value": "P1Y"
},
"expiryTime": {
"value": "P13M"
},
"notifyTimeBeforeExpiry": {
"value": "P30D"
},
"tags": {
"value": {
"bicep": "true",
"environment": "jorgebernhardt.com"
}
}
}
}
Important: Please note that the parameter file stores parameter values in plain text format. If you need to include a parameter with sensitive data, it’s recommended to store the value in a secure key vault.
Preview changes #
Before deploying a Bicep file, you can preview the changes that will occur to your resources. Using what-if operations does not change existing resources; it simply shows you an output that includes color-coded results that allow you to see different changes.
az deployment group what-if \
--resource-group <resource-group-name> \
--template-file <filename>.bicep \
--parameters @<filename>.parameters.json
Deploy the Azure resource #
Finally, to deploy the template, run the following command.
az deployment group create \
--resource-group <resource-group-name> \
--template-file <filename>.bicep \
--parameters @<filename>.parameters.json
Validate the deployment #
To verify that the resource was created correctly, you can either use the Azure Portal or the Azure CLI to check the created resources and their configurations. For Azure CLI, use the following command.
az keyvault key rotation-policy show \
--name <key-name> \
--vault-name <vault-name>
References and useful links #
Thank you for taking the time to read my post. I sincerely hope that you find it helpful.