C. Molendijk
C. Molendijk

Reputation: 2824

Azure Blueprint - Creating Web certificate from Key Vault secret gives access denied error

We got this big azure blueprint template that creates a lot of artifacts for us. One of the artifacts is the Azure Key Vault. The Key Vault gets created and the needed secrets are in there.

One of the other artifacts he tries to create is an Microsoft.Web/certificates. We try to create that with the below json

 {
    "name": "create-certificate",
    "kind": "template",
    "properties": {
        "template": {
            "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
            "contentVersion": "1.0.0.0",
            "parameters": {
                "name": {
                    "type": "string"
                },
                "location": {
                    "type": "string"
                },
                "vaultName": {
                    "type": "string"
                },
                "serverFarmId": {
                    "type": "string"
                }
            },
            "resources": [
                {
                    "type": "Microsoft.Web/certificates",
                    "name": "[parameters('name')]",
                    "apiVersion": "2016-03-01",
                    "location": "[parameters('location')]",
                    "properties": {
                        "keyVaultId": "[resourceId('Microsoft.KeyVault/vaults', parameters('vaultName'))]",
                        "keyVaultSecretName": "Origin-Certificate",
                        "serverFarmId": "[parameters('serverFarmId')]"
                    }
                }
            ]
        },
        "resourceGroup": "TD-RG",
        "parameters": {
            "name": {
                "value": "[concat(parameters('environmentSuffix'), '-Orgin')]"
            },
            "location": {
                "value": "[parameters('location')]"
            },
            "vaultName": {
                "value":"[concat(parameters('environmentSuffix'), '-Vault')]"
            },
            "ServerFarmId": {
                "value": "[artifacts('create-service-plan').outputs.ServerFarmId]"
            }
        },
        "dependsOn": ["create-service-plan", "create-key-vault"]
    }   
}

So it nicely waits that we first create an service plan and the key vault and then tried to read the orgin certificate from the key vault secret. The error that we then get is:

The service does not have access to '{KEY VAULT PATH}' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.

Searching the internet we found that we can give extra permissions to the key vault. With things like the following powershell command:

Set-AzureRmKeyVaultAccessPolicy -VaultName KEYVAULTNAME -PermissionsToSecrets get `
   -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd

Source of this script: Issue with KeyVault reference in ARM template

But the problem with this is, that the permissions are overwritten by the artifact definition that creates the key vault and so it can not be set trough Power shell. But I cannot get this right in the blueprint. For other users i already set permissions when we create the key vault and that works. But adding this like below doesn't work.

{
   "objectId": "abfa0a7c-a6b6-4736-8310-5855508787cd",
   "tenantId": "[parameters('tenantId')]",
   "permissions": {
     "secrets": [
       "get"
     ]
   }
 }

So now it stay's a riddle how to create an key vault and use an secret in the next artifact.

Upvotes: 0

Views: 234

Answers (1)

Joy Wang
Joy Wang

Reputation: 42043

I notice you used the same guid abfa0a7c-a6b6-4736-8310-5855508787cd both in the powershell Set-AzureRmKeyVaultAccessPolicy and ARM template, that was the cause.

In Set-AzureRmKeyVaultAccessPolicy, we need pass the Application ID(i.e. Client ID) for -ServicePrincipalName, description here. But in the ARM template, we need pass the Object ID of the service principal(not the App registration), it is different from the Application ID.

To get the Object ID of the service principal, you could use the powershell Get-AzureRmADServicePrincipal, in my screenshot, I use the new Az command, in your case, just use Get-AzureRmADServicePrincipal directly, the Id is the Object ID you need.

Note: Make sure your account logged in the powershell has the permission to get service principal in your AAD tenant.

Get-AzureRmADServicePrincipal -ApplicationId abfa0a7c-a6b6-4736-8310-5855508787cd

enter image description here

Then in your ARM template, use the Object ID instead of the Application ID, it will work fine.

{
   "objectId": "<Object ID>",
   "tenantId": "[parameters('tenantId')]",
   "permissions": {
     "secrets": [
       "get"
     ]
   }
 }

Upvotes: 0

Related Questions