Get the latest version of a certificate from an Azure key vault in an ARM template

azure key vault arm template access policy
microsoft.keyvault/vaults/secrets arm template
arm template key vault certificate
azure key vault encryption
azure key vault access policy
arm template reference
azure arm template
microsoft.keyvault/vaults/accesspolicies arm template

Creating an ARM template that needs to install an SSL certificate that is located inside of an Azure key vault. If I specify the certificate with the thumbprint, it works fine:

https://contoso.vault.azure.net/secrets/web01-test-contoso-com/968bf207451149d3aceb390065af9d3a

But as a certificate is on a ticking clock, this hard-codes a dependency that can go stale into the ARM template. I would rather just specify the latest version (like it shows in the portal). However, I haven't found any documentation that shows how to do that or even mentions if it is possible.

I ran a couple of experiments using:

https://contoso.vault.azure.net/secrets/web01-test-contoso-com

and

https://contoso.vault.azure.net/secrets/web01-test-contoso-com/latest

But in both cases, I got the same error message:

message '{
   "error": {
     "code": "InvalidParameter",
     "message": "https://contoso.vault.azure.net/secrets/web01-test-contoso-com/latest is 
 not a valid versioned Key Vault Secret URL. It should be in the format 
 https://<vaultEndpoint>/secrets/<secretName>/<secretVersion>.",
     "target": "certificateUrl"
   }
}'

So my question is: How can I reference the certificate in a way that I get the latest version?

For clarity, I am using the URL in the secrets section of the ARM template for a VM as follows, which gets the certificate from the Azure key vault and installs it into the Windows certificate store.

"secrets": [
    {
      "sourceVault": {
        "id": "[resourceId(parameters('keyVaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
      },
      "vaultCertificates": [
        {
          "certificateUrl": "https://contoso.vault.azure.net/secrets/web01-test-contoso-com/latest",
          "certificateStore": "My"
        }
      ]
    }
]

NOTE: I would find it odd that you can specify the latest version of an OS to install, but you cannot specify to install the latest version of a certificate.

It is possible, contrary to what accepted answer says . Define variable with secret's resource id like this, for example:

"mySecretResourceId": "[concat(resourceGroup().id,'/providers/Microsoft.KeyVault/vaults/', variables('keyVaultName'), '/secrets/', 'my-secret-name')]"

then you can use it in your template as following:

"certificateUrl": "[reference(variables('mySecretResourceId'), '2018-02-14').secretUriWithVersion]"

Key Vault secret with template, Use Azure Key Vault to pass secure parameter value during For a quickstart template of that scenario, see Install a certificate from --name ExampleVault \ --​secret-permissions set delete get list If you need to use a version of the secret other than the current version, use the secretVersion property. Create an Application Gateway V2 with Key Vault: This template deploys an Application Gateway V2 in a Virtual Network, a user defined identity, Key Vault, a secret (cert data), and access policy on Key Vault and Application Gateway. Create an Azure Key Vault and a secret: This template creates an Azure Key Vault and a secret.

There is no direct\easy way of doing this. Key Vault isnt exactly arm template friendly.

As juunas proposed you can write a script or use custom script extension to pull that data directly from key vault using managed service identity, for example.

Use Azure Key Vault in templates, Learn how to use Azure Key Vault to pass secure parameter values Tutorial: Integrate Azure Key Vault in your ARM template deployment $keyVaultName = $projectName $adUserId = (Get-AzADUser -UserPrincipalName $upn). /​tutorials-use-key-vault/CreateKeyVault.json" New-AzResourceGroup  Create certificates for Azure Key Vault. This process consists of three steps: Create the security certificate. Create the Azure Key Vault to store the certificate. Store the certificates to the key vault. You can use either a new or an existing Azure resource group for this work. Create the security certificate

According to @4c74356b41's aswer I did it by my self in python script.

      data = json.loads(kv_auth_response.content)
      #
      ## Lets find youngest vesrion of certificate
      #
      if len(data['value']) > 0:
         for x in range(len(data['value'])):
             if x == 0:
                youngest = data['value'][x]['attributes']['exp']
                cert_url = data['value'][x]
             if data['value'][x]['attributes']['exp'] > youngest:
                youngest = data['value'][x]['attributes']['exp']
                cert_url = data['value'][x]
         arry = cert_url['id'].split('/')
...
         cert_version = arry[len(arry)-1]

At the first step of the loop, value of expire date is assigned to the "youngest" variable. In the next steps script compares expire date with it and assigns when the condition is met. After loop script splits with "yougests" cert_url and assigns last part of array to "cert_version" variable.

Full view of this problem you can see in my script to BYOC for custom domain. Link: https://github.com/przemika/azure-byoc-for-custom-domain/blob/master/start-byoc.py

Announcing an easier way to use latest certificates from Key Vault , When we launched Azure Key Vault a few years ago, it solved a major Developer also chooses to receive an email when a certificate is about to expire latest version of the secret (for the purpose of this article a certificate) is just as with an ARM template which also includes creating a Key Vault VM  More Azure Key Vault template samples can be found in Azure Quickstart Templates. Deploy the template. Select the following image to sign in to Azure and open a template. The template creates a key vault and a secret. Select or enter the following values. Unless it's specified, use the default value to create the key vault and a secret.

About Azure Key Vault keys, secrets and certificates, When an object is first created, it's given a unique version identifier and marked as the current version of the object. Creation of a new instance  In this post, the problem of pushing a certificate from a customer managed key vault to your VM is solved. This is done by copying the certificate as a secret and specially formatting it into a JSON object that is saved as a secret in a key vault in the same region as the VM, then referencing that secret during the ARM template deployment.

Set and retrieve a secret from Azure Key Vault using an ARM template, Quickstart showing how to create Azure key vaults, and add secrets to the for secrets, such as keys, passwords, certificates, and other secrets. an Azure Resource Manager template (ARM template) to create a key vault and a secret. Get it by using Get-AzADUser or Get-AzADServicePrincipal cmdlets. Instead of putting a secure value (like a password) directly in your template or parameter file, you can retrieve the value from an Azure Key Vault during a deployment. You retrieve the value by referencing the key vault and secret in your parameter file.

Microsoft.KeyVault/vaults/secrets 2019-09-01, KeyVault/vaults/secrets JSON syntax and properties to use in Azure Resource Manager templates for deploying the resource. API version 2019-09-01. Get started · Reference architectures · Architecture framework · Design patterns using this model are is intended for internal use in ARM deployments. For more details, see Get started with Azure Key Vault certificates. Contact Information Contact RM_Customer_Queries@microsoft.com if you discover issues using the task, to share feedback about the task, or to suggest new features that you would like to see.

Comments
  • In the case this isn't possible, you could write a script that does this after ARM deployment.
  • In your pipeline, add a script that gets the latest version, and then pass it as a parameter into arm template.
  • can be simplified: resourceId('Microsoft.KeyVault/vaults/secrets', 'kvname', 'secret name'). nice catch though
  • @4c74356b41 It can be simplified only if the resource (key vault secret in this case) already exists. But if the resource is defined in the same template resourceId() function call will fail. So building resource id manually using concat() seem to be the only option.
  • no, thats not true, it doesnt matter if the resource exist at all. resourceId() will always work