Azure Resource Manager - Using secrets in ARM templates



In this series so far, you have seen how you can get started with ARM templates, parameterize the templates by adding parameters, and then optimize those templates using variables, expressions, and user-defined functions. It is now time to move forward into more advanced topics and start building the template for the remaining components in the architecture shown above. In the architecture shown above, you will be implementing an ARM template that will provision virtual machines for which the administrator and domain-join credentials will have to provided as input. Also, the configuration scripts used for guest OS configuration may have to access an internal storage account blob which will require the storage connection strings and access keys. Storing these secrets in plain-text is not recommended at all. Also, as an architect, you may want to standardize on the passwords used for local administrator accounts and do not want to share the domain-join credentials with any user while provisioning an ARM template. This needs a more centralized credential and secret store. Azure Vault provides this capability. Today, you will see how to handle secrets such as passwords, access keys, certificates, and so on in an ARM template.

Azure Key Vault

Azure Key Vault is a service that provides a centralized secret store. You can use the Key Vault for cryptographic keys, API keys, passwords, connection strings, and certificates. For the cryptographic keys, you can use a Hardware Security Module (HSM) as well. Once a key vault is provisioned, you can add your secrets and retrieve them in an ARM template for use with other resource types such as virtual machines.

Creating a key vault

To create a key vault, you need few mandatory input parameters such as tenantId, objectId of the user or service principal or the security group in Azure Active Directory (AAD), key and secret permissions. The specified tenant will be used for authenticating requests to the key vault and the object Id of the AAD user will be used to provide the necessary permissions to interact with the Key Vault.

Here is a simple starter template that you can use.

In this starter template, you see that the value of tenantId defaults to the value of the tenantId property from the subscription() standard template function. The value to the objectId property is coming from a template parameter. You can retrieve the object ID of an AAD user using az ad user show command.

az ad user show --id Ravikanth@azure.com --query objectId

You can deploy the above template to create a Key Vault by clicking on the Deploy To Azure button below.


If you prefer Azure CLI, you can use the following commands to perform this template deployment.

In the above template, as a part of the access policies [line 22], for key, secrets, certificates permissions, you have used all as the value. As it literally means, this permission level provides full permission set to the service principal specified using objectId property. This is not recommended in a production Key Vault. You must secure the key vault as well and restrict access to what is really needed. The allowed values for the key and secret permissions can be seen in the resource provider reference.

To this extent, the above template can be modified to add a few more parameters to enable permission value specification.

In this updated template, three additional parameters are added to gather key, secret, and certificate permissions. While there are default values for these parameters, you can provide updated set of permissions as an array during deployment time. If you notice, there are additional resource properties as well added to the Key Vault resource definition.

enabledForDeployment spcifies whether Azure virtual machines can retrieve the certificates from the key vault or not.

enabledForTemplateDeployment specifies whether Azure Resource Manager is allowed to retrieve secrets from the vault or not.

For the architecture that you are building, both these properties need to be set to true.

You can try deploying this template by clicking on the Deploy to Azure button below.


Now, with this updated template you have a functional key vault that can be used to store secrets needed for other resource configurations. So, how do you use ARM templates to store secrets in a key vault?

Adding secrets to vault

Once you have a key vault provisioned, you can add the Microsoft.KeyVault/vaults/secrets resource to the template to add secrets to the vault. The following resource definition will do that job.

{
	"type": "Microsoft.KeyVault/vaults/secrets",
	"name": "[concat(variables('keyVaultName'), '/', parameters('secretName'))]",
	"apiVersion": "2018-02-14",
	"location": "[resourceGroup().location]",
	"properties": {
		"value": "[parameters('secretValue')]",
		"contentType" : "string"
	}
}

In this resource definition, the type of the resource is Microsoft.KeyVault/vaults/secrets. The secretName that you want to use will be provided as the name of the resource and the value will be set in the resource properties.

Here is the full template that can be used to provision a key vault and then add a secret to it.

This updated template added two more parameters – secretName and secretValue. secretValue is a secure string. Try deploying the template using the deploy to Azure button below.


Retrieve vault secret

Finally, when you have to use the secret as another resource property value, you can do that using a property definition as shown below.

"adminPassword": {
    "reference": {
        "keyVault": {
        "id": "/subscriptions/<SubscriptionID>/resourceGroups/mykeyvaultdeploymentrg/providers/Microsoft.KeyVault/vaults/<KeyVaultName>"
        },
        "secretName": "vmAdminPassword"
    }
}

You will learn more about this pattern in the later articles of this series when you attempt creating virtual machines using ARM template.

Summary

In this part, you learned how to create an Azure Key Vault, add secrets to the vault, and retrieve the secrets. This knowledge will come handy when you attempt creating virtual machines that require a predefined administrator password. In the next part, you will learn about resource dependencies in ARM templates.

Share on: