In this article, I will explain how we can create an Azure Key vault; add secrets to an Azure Key Vault, and how we can add a web app service principal into the vault access policy using simple ARM templates.
Before beginning to create an ARM template, the assumption here is that you should have a basic understanding of the structure of ARM templates and you already have a resource group.
The Context
For demonstration purposes, we will create a web app with a system-assigned identity and we will add web app service principal id to the key vault access policy. Similarly, we will create a storage account to demonstrate how we can easily add storage account connection string into key vault secret.
We will create the below resources in this article for better understanding purposes.
| Resource Name |
Type reference |
| Key Vault |
Microsoft.KeyVault/vaults |
| Key Vault - Secret |
Microsoft.KeyVault/vaults/secrets |
| Storage Account |
Microsoft.Storage/storageAccounts |
| Web App |
Microsoft.Web/sites |
| App Service Plan |
Microsoft.Web/serverfarms |
The below image represents the resources dependency of our ARM templates which we will build in subsequent steps.
![]()
And we will follow the below-maiming convention while creating resources using ARM. Image has been referred from Microsoft documentation.
![]()
Let’s build our template step by step for each resource.
Parameters & Variables
We are taking environment name as Input and in the variable, we will concatenate environment name with resources we are creating.
"parameters": {
"envName": {
"defaultValue": "uat",
"type": "String"
}
}, "variables": {
"tenantId": "[subscription().tenantId]",
"appServicePlanName": "[concat('plan-myapp-',parameters('envName'),'-',resourceGroup().location)]",
"webAppName": "[concat('app-mywebapp-',parameters('envName'),'-',resourceGroup().location)]",
"storageAccountName": "[concat('stmystorage',parameters('envName'),resourceGroup().location)]",
"keyVaultName": "[concat('kv-myapps-',parameters('envName'),'-',resourceGroup().location)]"
},
Creating Key Vault with Vault Access Policy
To create a Key Vault with an access policy, we add the following resource to the ARM template.
First, we will create a web app with an app service plan.
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('appServicePlanName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "S1",
"tier": "Standard",
"size": "S1",
"family": "S",
"capacity": 1
},
"kind": "app"
}, {
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('webAppName')]",
"location": "[resourceGroup().location]",
"dependsOn": ["[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"],
"kind": "app",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"name": "[variables('webAppName')]",
"httpsOnly": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
}
},
Let’s create a key vault with an access policy. Here, we included an access policy as the service principal id of a web app that we are creating. This will ensure that our web app reads the connection string directly from Key Vault as we are implementing Managed Service Identity.
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2021-04-01-preview",
"name": "[variables('keyVaultName')]",
"location": "[resourceGroup().location]",
"properties": {
"sku": {
"family": "A",
"name": "Standard"
},
"tenantId": "[variables('tenantId')]",
"accessPolicies": [{
"tenantId": "[variables('tenantId')]",
"objectId": "[reference(concat('Microsoft.Web/sites/',variables('webAppName')), '2018-11-01','Full').identity.principalId]",
"permissions": {
"keys": [],
"secrets": ["Get"],
"certificates": []
}
}],
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": false,
"enableSoftDelete": true,
"enableRbacAuthorization": false,
"vaultUri": "[concat('https://' ,variables('keyVaultName'),'.vault.azure.net/')]",
"provisioningState": "Succeeded"
}
},
Adding Storage Account Connection string as a Secret
First, we will add a Storage Account resource to the ARM template.
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "[variables('storageAccountName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "Storage",
"properties": {
"supportsHttpsTrafficOnly": true
}
},
Now we will add a Secret called “StorageAccountConnectionString” that is depending on the Storage Account and the Key Vault defined earlier. The value of this secret is set with a connection string containing the access key of the Storage Account that we created earlier.
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2021-04-01-preview",
"name": "[concat(variables('keyVaultName'), '/StorageAccountConnectionString')]",
"location": "[resourceGroup().location]",
"dependsOn": ["[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]", "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"],
"properties": {
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')),'2017-06-01').keys[0].value)]"
}
}
Deploying ARM Template using Azure CLI
Using Azure CLI, we will deploy this template. Here, my templates name is “ARM_KV_Template.json” and I have a resource group created already. First, I uploaded the JSON file using the upload option and then executed the below script in Bash.
az deployment group create --resource-group rg-myapps-uat-westus --template-file ARM_KV_Template.json
![Create An Azure Key Vault With Vault Access Policy And Add Secrets Using ARM Template]()
Now if you go to the resources group, you will see all the resources are created successfully.
![Create An Azure Key Vault With Vault Access Policy And Add Secrets Using ARM Template]()
Let’s check key vault secrets and access policies one by one.
![Create An Azure Key Vault With Vault Access Policy And Add Secrets Using ARM Template]()
![Create An Azure Key Vault With Vault Access Policy And Add Secrets Using ARM Template]()
Excellent! We are done with your implementation and we deployed Azure Key vault with an access policy and secret using ARM templates.
Hope you found this article useful.
Happy Learning!