Whenever you deal with ARM templates, you always face to handle some sensitive information. This is mainly for API keys handling. How can you cope with those values other than hard-code them into the templates? There are six different ways to handle them we’re going to discuss in this post.
Some Azure resources generate their access keys after they are provisioned. Here are some examples: Application Insights, Azure SQL Database, Cosmos DB, Storage Account, Service Bus, Functions, and Logic Apps. They can be directly accessible within the ARM templates, without knowing them, as long as we know their resource IDs. As I wrote the relevant post a while ago, here in this post, I’m not going further but leaving the link to the post.
List of Access Keys from Output Values after ARM Template Deployment
listKeys
for Storage Account, listSecrets
for Azure Functions and reference
for Application InsightsThose ARM template functions internally use ARM REST APIs, which means resources not on Azure can’t use them. In addition to this, inconsistency on the ARM function names and signatures have made this useful feature not very popular, which is a bit sad. But when you start using this, it will be powerful.
SecureString
to Pass Values via ParametersThis is the most common and popular way of handling secrets. ARM template parameters have data type of string
, int
, bool
, securestring
, secureobject
. Using the securestring
data type only accepts the encrypted value. Therefore no one can recognise the value. In fact, an ARM template uses the securestring
data type like this way:
NOTE: I’ve deliberately written ARM templates in both YAML and JSON. As you know YAML is not officially supported yet, but is very powerful to use. If you’re interested in YAML authoring, have a look at this post.
If you set up the ARM template like above, values are encrypted and passed directly to the template or through CI/CD pipelines. Here’s how values are encrypted in PowerShell and passed it to the cmdlet.
If you use Azure CLI, this is the command.
SecureString
value can be easily generated and used straight away.I can’t say this type of compromising won’t happen.
Now, we know Azure Key Vault is used for this type of practice. First of all, we can directly integrate Azure Key Vault with ARM templates. If you use a parameter file, Azure Key Vault can be referenced within the parameter file. The following code snippet describes how to set up parameters for Azure Logic App.
In the parameter file below, you can introduce the Azure Key Vault reference.
Is there any other way to avoid that hard-coded value? Of course, there is.
Without needing to hard-code Azure subscription ID, we can still refer to Azure Key Vault instance. In order to achieve this, we should use the linked templates. In other words, we need to write another linked template for this purpose.
The resourceId
the function is the key to this approach.
If your organisation has already been using those linked template approaches, that wouldn’t be an issue; otherwise, your organisation will start worrying about extra maintenance efforts on those linked templates.
Instead of referencing Azure Key Vault within ARM templates, you can also let your preferred CI/CD pipeline handle them. Here in this post, I’m using Azure Pipelines in Azure DevOps. First of all, the secret name stored in Azure Key Vault looks like this:
This Azure Key Vault instance can be referenced by the Key Vault task in each pipeline.
Set up the Azure Subscription and Key Vault instance, then enter the secret name.
Then reference the secret name in the ARM Template Deployment task.
If your CI/CD pipeline supports common libraries, like Azure Pipelines, we can integrate Azure Key Vault instance with the common library. Create a common library and enable Azure Key Vault integration.
Once Azure Key Vault is linked to the library, register the library in the variable groups tab.
Then give the reference in the ARM Template Deployment task.
To sum up, we’ve walked through six different ways of handling secrets around ARM templates. As each approach has its own pros and cons, we can’t tell which way is better than the others. It really depends on the situation and requirements, nonetheless.
This has been cross-posted to DevKimchi.