Reputation: 501
So I'm trying to codify all my Azure infrastructure using Azure Devops Pipelines and ARM templates. It's pretty tough going but I can see the benefit when a deployment delivers me 20 resources in 5 minutes which are all good-to-go!
However, I have hit a problem. I want to deploy a new Keyvault. Tick, easy! I want to store a x509 certificate which is a wildcard cert used by my Web Apps. Tick easily done. Now I want to create a "Microsoft.Web/Certificates" certificates resources which I can then use to create an SSL custom binding for my Web Apps. This fails:
"The service does not have access to '...microsoft.keyvault/vaults/gs-prd1-kv-apps' Key Vault.
This is reasonably well documented in the sample template here: https://github.com/Azure/azure-quickstart-templates/tree/master/201-web-app-certificate-from-key-vault. It turns out that the **Microsoft.Azure.Websites" resource provider does not have access to the Keyvault. To get around this the guidance is to run a powershell or az cli command to add the RP to my new Keyvault
Set-AzureRmKeyVaultAccessPolicy -VaultName KEY_VAULT_NAME -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd -PermissionsToSecrets get
Problem is, I need to do this in the Devops pipeline or ARM template and I have absolutely no idea how.
I have tried to add the az command into a new build task, but the service principle which is running the pipeline ALSO does not have the correct permissions to add it in.
Can anyone help? There MUST be a way of deploying a Keyvault with x509 cert and assigning this resource to a Web App?
Upvotes: 1
Views: 681
Reputation: 501
I thought I would share my now working solution to this issue. So lets clarify what we want to deploy within the ARM template:
This would all work fine except that the resource provider used to create the App Service Plan does not have an access policy for the new Keyvault and cannot, therefore, extract the x509 cert. This is documented in the sample template referenced in the question. The guidance is to run a command to add an access policy for the resource provider. However, as I state in the question, we are trying to do this entirely within the ARM template.
The solution is to define the access policy for the resource provider within the ARM template. However, there are two problems:
I took a hint from this SO question and did the following.
1. Create new Keyvault and add the x509 certificate to it as a secret
2. Run an az CLI command to get service principal for the "Microsoft Azure App Service"
az ad sp list --display-name "Microsoft Azure App Service"
This displays a lot of properties for the service, including the [objectId] which I can copy for use in the ARM template
3. Create a Keyvault Access Policy resource in the ARM template for the "Microsoft Azure App Service" service principal - using the [objectId] above. Grant this principal "Get" permissions for secrets only.
4. Create App Service Plan and a new Web certificate resource for it
Now when I run the template which the Microsoft Azure App Service principal has permission to retrieve the x509 cert from the new Keyvault and create a web certificate resource in the service plan.
Upvotes: 2