How to import certificate from Key Vault using Azure RBAC access

Introduction

Recently I had an issue trying to use ARM to import a private certificate from the KeyVault to an App Service. I browsed through all the documentation I found on the official site. That unfortunately didn’t help at all. In the end, though not giving up and digging more into it I found a solution.

Just to give an example. I had a certificate present in the KeyVault and to link(import) it to the Azure function I had to do some extra steps.

Prerequisites

First what is needed for this scenario:

  1. Have an existing KeyVault
  2. Have an imported Certificate in Keyvault
  3. Use Azure RBAC instead of Access Policies in your KeyVault

import certificate from Key Vault using Azure RBAC access

  1. Example ARM template:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "hostingPlanName": {
            "type": "string"
        },
        "hostingPlanResGroup": {
            "type": "string"
        },
          "vaultName": {
            "type": "string"
        },
         "certificateName": {
            "type": "string",
            "defaultValue": "myCertificateName"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Web/certificates",
            "name": "[parameters('CertificateName')]",
            "apiVersion": "2020-12-01",
            "location": "[resourceGroup().location]",
            "properties": {
                "keyVaultId": "[resourceId('Microsoft.KeyVault/vaults', parameters('vaultName'))]",
                "keyVaultSecretName": "[parameters('certificateName')]",
                "serverFarmId": "[resourceId(parameters('hostingPlanResGroup'),'Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
            }
        },
        {
            "type": "Microsoft.KeyVault/vaults/secrets",
            "apiVersion": "2019-09-01",
            "name": "[concat(parameters('vaultName'), '/CertificateThumbprint')]",
            "location": "[resourceGroup().location]",
            "properties": {
                "value": "[reference(resourceId('Microsoft.Web/certificates', parameters('certificateName'))).Thumbprint]"
            }
        }
    ]
}

Now deploying this ARM template right away you will get an exception like this: The service does not have access to '/subscriptions/9f9ccb20-c2ae-4648-b52e-907b54ad3cfc/resourcegroups/your-resource-rg/providers/microsoft.keyvault/vaults/your-keyvault-kv' Key Vault. Please make sure that you have granted the necessary permissions to the service to perform the request operation.

  1. Now to run this ARM template we first need to add few roles in the KeyVault. Otherwise, this will fail as I initially failed.

The user/Service Principal running this needs to have KeyVault Certification Officer and KeyVault Secrets User roles. That can be added either through Azure Portal, Az CLI cloud shell ARM template, or Az CLI PowerShell,´. For simplicity, I would add these roles through Azure Portal