azureazure-keyvaultazure-webappsazure-rbac

Assigning web app with keyvault reference does not work via BiCep


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. enter image description here

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.


Solution

  • 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.

    enter image description here

    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:

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    After deployment succeeded, I gave permission to my user to show the certificate created by webapp.

    enter image description here

    Refer:

    https://learn.microsoft.com/en-us/cli/azure/keyvault/certificate?view=azure-cli-latest#az-keyvault-certificate-create

    https://learn.microsoft.com/en-us/azure/templates/microsoft.resources/deploymentscripts?pivots=deployment-language-bicep#resource-format