Create Key Vault keys using ARM templates and Azure Blueprints
This post intents to explain the steps to create Key Vault keys using Resource Manager templates (ARM), by invoking a Custom Resource Provider using an Azure Function App endpoint that will be in charge of executing a function that creates Key Vault keys.
The full deployment assumes the use of Azure Blueprints to help orchestrate the deployment of the different resources.
Important Note:
This blog post can be read in order or start with step 0, and then jump straight to step 8 to run the full orchestrated deployment using Azure Blueprints.
It is strongly recommended to read steps 1–7 to understand what each ARM template is doing.
Step 0. Pre-requirements and GitHub repo
As pre-requirements, you’ll need to have installed the following components:
- Azure CLI or Azure Powershell to run Azure Resource Group deployments
- Azure Blueprints module for Azure Powershell
There’s an option to interact with Azure Blueprints APIs by directly invoking the REST APIs, but, is actually more convenient to use the Powershell version — that helps to authenticate the API requests — , this version requires Azure Powershell, which means, Azure Powershell and Azure Blueprints module are required.
Now, let’s clone the following repo:
https://github.com/jorgecotillo/az-blueprints
Step 1. Create a Custom RP Resource Group
First, and create a Resource Group called custom-resource-provider-rg
Azure Powershell:
New-AzResourceGroup -Name “custom-resource-provider-rg” -Location “westus2”
Azure CLI:
az group create — name “custom-resource-provider-rg” — location “westus2”
Make sure you are logged into Azure by either running Login-AzAccount (Azure Powershell) or az login (Azure CLI) and are located in the right subscription Set-AzContext -Subscription “SubcriptionName” (Azure Powershell) or az account set — subscription “subscriptionName” (Azure Powershell)
Step 2. Create an Azure Function App
Once the Resource Group has been created, then let’s run the Azure Function deployment.
Go to the following directory:
[path_to_your_cloned_repo]\az-blueprints\armTemplates\azureFunction
Run the following command:
Azure Powershell:
New-AzResourceGroupDeployment -ResourceGroupName “custom-resource-provider-rg” -TemplateFile deploy.json
Azure CLI:
az group deployment create — template-file deploy.json — resource-group “custom-resource-provider-rg”
Azure Powershell or Azure CLI deployment will prompt for input parameters, enter the values and wait for the deployment to complete.
This Resource Manager template creates an Azure Function using System assigned managed identity, along with the corresponding App Plan (Consumption only mode).
System assigned managed identity is used later to grant a Key Vault Access Policy to create encryption keys.
This template contains the respective Function — coded in C# — which is the one in charge of creating the encryption key.
The code looks like the following:

Lines 30–34 are getting the access token to authenticate against Azure Control Plane, since the Azure Function is using System assigned managed identity, there is no need to provide credentials to authenticate against Azure.
Lines 35–41 are creating the proper Key Vault encryption key.
Note that the response is creating an instance of an object of KeyResource class, this object has one single property and is called “properties”, this is required later by the Custom Resource Provider to be able to capture the returned value.

Step 3. Create a Custom Resource Provider
Go to the following directory:
[path_to_your_cloned_repo]\azblueprints\armTemplates\customRPDefinition
Run the following command:
Azure Powershell:
New-AzResourceGroupDeployment -ResourceGroupName “custom-resource-provider-rg” -TemplateFile deploy.json
Azure CLI:
az group deployment create — template-file deploy.json — resource-group “custom-resource-provider-rg”
Azure Powershell or Azure CLI deployment will prompt for input parameters, enter the values and wait for the deployment to complete.
This template creates a Custom Resource Provider that uses the Azure Function’s endpoint created in step 2. When invoking the Custom Resource Provider from an ARM template, Azure internally invokes the endpoint specified and passes the body of the request as a JSON object, we’ll discuss more about the invocation in step 7.

Notice that resourceTypes is an array, which means that more endpoints can be added, for example, an endpoint that enables NSG Flow Logs, or one that creates Management Groups, etc, etc.
Step 4. Create a Key Vault Resource Group
Now, let’s create a Resource Group called keyvault-rg
Azure Powershell:
New-AzResourceGroup -Name “keyvault-rg” -Location “westus2”
Azure CLI:
az group create — name “keyvault-rg” — location “westus2”
Step 5. Create a Key Vault resource
Go to the following directory:
[path_to_your_cloned_repo]\az-blueprints\armTemplates\keyVault
Run the following command:
Azure Powershell:
New-AzResourceGroupDeployment -ResourceGroupName “keyvault-rg” -TemplateFile deploy.json
Azure CLI:
az group deployment create — template-file deploy.json — resource-group “keyvault-rg”
Azure Powershell or Azure CLI deployment will prompt for input parameters, enter the values and wait for the deployment to complete.
Step 6. Key creation using Custom Resource Provider
Go to the following directory:
[path_to_your_cloned_repo]\azblueprints\armTemplates\createKeyVaultKeys
Run the following command:
Azure Powershell:
New-AzResourceGroupDeployment -ResourceGroupName “custom-resource-provider-rg” -TemplateFile deploy.json
Azure CLI:
az group deployment create — template-file deploy.json — resource-group “custom-resource-provider-rg”
Azure Powershell or Azure CLI deployment will prompt for input parameters, enter the values and wait for the deployment to complete.
Step 7. Use Key Vault Keys
Go to the following directory:
[path_to_your_cloned_repo]\azblueprints\armTemplates\retrieveKeyVaultKeys
Run the following command:
Azure Powershell:
New-AzResourceGroupDeployment -ResourceGroupName “custom-resource-provider-rg” -TemplateFile deploy.json
Azure CLI:
az group deployment create — template-file deploy.json — resource-group “custom-resource-provider-rg”
Azure Powershell or Azure CLI deployment will prompt for input parameters, enter the values and wait for the deployment to complete.
Once the deployment completes, the template outputs will be printed on the screen, these outputs belong to the encryption keys created in step 6.
Step 8. Glue all together — Azure Blueprints
Now, to simplify these deployment steps, Azure provides a platform native orchestration of artifacts (ARM templates, Azure Policies and RBAC) called Azure Blueprints, if you are not familiar with it, I strongly recommended reading through the documentation.
This step assumes familiarity with Azure Blueprints to publish a Blueprint definition (make it available) and to execute a Blueprint assignment (deployment of artifacts).
From the cloned repo, go to the following directory:
[path_to_your_cloned_repo]\az-blueprints\azBlueprint
Run the following command:
Azure Powershell:
Import-AzBlueprintWithArtifact -InputPath .\ -Name “custom-rp” -ManagementGroupId “Your_ManagementGroup_Id”
This cmdlet creates a new Blueprint definition in your management group.
Make sure to have access to the management group specified
From this point, you’ll need to:
- Access the Azure Portal
- Click on to Policy
- Click on Blueprints


4. Click on Blueprint definitions
5. Click on custom-rp

6. Click on Publish blueprint

7. Provide a version number and click Publish

8. Click on Assign blueprint

9. Select a Subscription, and enter an organization name

10. Click assign, sit back, relax and wait for the assignment to complete
Once the Blueprint assignment is complete:
- Go to the Azure Portal
- Go to Resource Groups — make sure to select the Subscription where the Blueprint got assigned
- Click on jumpbox-rg
- Click on Deployments

5. Click on the deployment that has the latest Last modified date

6. Click on Outputs

Look at the results … Encryption Keys created using Azure Blueprints and Custom Resource Provider!
Hope you find this post useful.
Happy coding!
