When deploying our web app application, we knew that we wanted to import certificates to web app from Key vault. However, we've managed to get a lot of issues along the way and wanted to see if there is someone else who has run in to the same issues and have some feedback/helpful ways to move forward.
First things first: Deployment method: Bicep w. service principal Permission Model Key Vault: Access Policy Applications: Web App (Linux, App Service plan) & Key Vault
First time we tried to deploy, we got into the issue where our only error was:
The service does not have access to '/subscriptions/<our-subscription>/resourcegroups/<our-resource-group>/providers/microsoft.keyvault/vaults/<our-keyvault>' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.
When looking online we stumbled onto another MS thread that had this exact issue (see issue here) and so we switched from using RBAC permission model to using Access Policy instead on the keyvault. Even though we switched to access-policy and assigned our user assigned managed identity to the kv , we still couldn't get it to work. Then we tried with Assigning 'Microsoft Azure App Service' role, which makes the workflow work. The only trouble we have with this is that we have to assign the role manually in the Azure platform and not by using Bicep.
Whenever we've tried to create an access policy with Bicep using the id for 'Microsoft Azure App Service' (abfa0a7c-a6b6-4736-8310-5855508787cd), we only get it to show up like picture below and "unknown" (which in turn results in us not being able to add certficate to web app from key vault.
Has anyone experienced the same issue or have a workaround for this?
Since this is a complicated workflow we want to make sure that we can document as much as possible in our code.
Assigning web app with keyvault reference does not work via Bicep
You're right, assigning webapp to create a certificate in key vault with relevant permission is not possible because as per the Microsoft Documentation among the list of available resources I don't find any provisioning scripts to set up certificates.
Which results in the blocker you mentioned in the query occurs when you use the below bicep plugin, which don't exist as per the GitHub Issue.
resource keyVaultCertificate 'Microsoft.KeyVault/vaults/certificates@2023-02-01'
Instead, you can leverage CLI for the certificate creation. If you still want to achieve the using bicep, you can use the configuration as I mentioned below.
Demo configuration:
resource webAppIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: managedIdentityName
location: location
}
resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
name: keyVaultName
location: location
properties: {
enabledForDeployment: true
enabledForTemplateDeployment: true
enabledForDiskEncryption: true
tenantId: subscription().tenantId
accessPolicies: []
sku: {
family: 'A'
name: 'standard'
}
}
}
resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = {
name: appServicePlanName
location: location
sku: {
name: 'B1'
tier: 'Basic'
}
}
resource webApp 'Microsoft.Web/sites@2024-04-01' = {
name: webAppName
location: location
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: ''
}
}
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${webAppIdentity.id}': {}
}
}
}
resource keyVaultAccessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2023-02-01' = {
name: 'add'
parent: keyVault
properties: {
accessPolicies: [
{
objectId: webAppIdentity.properties.principalId
tenantId: subscription().tenantId
permissions: {
secrets: ['get', 'list']
certificates: ['get', 'list','create', 'import']
}
}
{
objectId: 'abfa0a7c-a6b6-4736-8310-5855508787cd'
tenantId: subscription().tenantId
permissions: {
secrets: ['get']
certificates: ['get', 'list', 'import']
}
}
]
}
}
resource webAppConfig 'Microsoft.Web/sites/config@2022-03-01' = {
parent: webApp
name: 'web'
properties: {
appSettings: [
{
name: 'WEBSITE_LOAD_CERTIFICATES'
value: '*'
}
{
name: 'KeyVaultReferenceIdentity'
value: webAppIdentity.id
}
]
}
}
resource createCertificateScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
name: 'createCertificate'
location: location
kind: 'AzureCLI'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${webAppIdentity.id}': {}
}
}
properties: {
azCliVersion: '2.40.0'
timeout: 'PT5M'
retentionInterval: 'P1D'
scriptContent: format('''
az keyvault certificate create --vault-name {0} --name testsv-demo-cert --policy "$(az keyvault certificate get-default-policy)"
''', keyVault.name)
}
dependsOn: [
keyVaultAccessPolicy
]
}
Deployment:
After deployment succeeded, I gave permission to my user to show the certificate created by webapp.
Refer: