Cloud & Engineering

Justin Yoo

6 Ways Passing Secrets to ARM Templates

Posted by Justin Yoo on 24 April 2019

Azure Resource Manager, ARM Templates, DevOps, Azure Key Vault, Azure Pipelines, YARM CLI, Azure DevOps, Linked Templates

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.

1. Use ARM Template Functions to Pass Values Internally

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

  • Pros
    • Keys don’t need to be stored anywhere
    • Keys can be directly accessible via ARM template functions within the templates
  • Cons
    • Keys from outside Azure can’t be accessible
    • ARM template functions are not consistent. eg) listKeys for Storage Account, listSecrets for Azure Functions and reference for Application Insights

Those 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.

2. Use SecureString to Pass Values via Parameters

This 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.

  • Pros
    • SecureString value can be easily generated and used straight away.
    • Environment variables in CI/CD pipeline can have encrypted values and are passed to the template.
  • Cons
    • In a rare case, while the plain text value is stored in the CI/CD pipeline, it might be compromised before being encrypted by the pipeline.
    • While encrypting those values within the PowerShell environment, they might be compromised on the screen.

I can’t say this type of compromising won’t happen.

3. Integrate Azure Key Vault with ARM Templates Directly

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.

  • Pros
    • Existing ARM templates are not changed.
    • Only parameter files are changed to include Azure Key Vault references.
  • Cons
    • Within the parameter file, the Azure Key Vault resource ID must be hard-coded.
    • The hard-coded resource ID includes the subscription ID, which might be considered sensitive data.

Is there any other way to avoid that hard-coded value? Of course, there is.

4. Integrate Azure Key Vault with ARM Templates Indirectly

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.

  • Pros
    • There is no hard-coded value required.
  • Cons
    • Additional linked templates should be written.

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.

5. Integrate Azure Key Vault Task with Each CI/CD Pipeline

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.

  • Pros
    • Existing ARM templates are not touched.
    • There is no dependency on the CI/CD environment variables.
    • All secrets are managed by Azure Key Vault.
  • Cons
    • Each pipeline has to set up the Key Vault task to access to Key Vault, which is cumbersome.

6. Integrate Azure Key Vault with Common Library in CI/CD Pipeline

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.

  • Pros
    • Existing ARM templates are not touched.
    • There is no dependency on the CI/CD environment variables.
    • All secrets are managed by Azure Key Vault.
    • Each pipeline doesn’t need to set up Azure Key Vault integration.
  • Cons
    • The common library might get bigger, as all necessary secrets need to be registered up-front.

Conclusion

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.

What’s Next?

 

This has been cross-posted to DevKimchi.

 

If you like what you read, join our team as we seek to solve wicked problems within Complex Programs, Process Engineering, Integration, Cloud Platforms, DevOps & more!

 

Have a look at our opening positions in Deloitte. You can search and see which ones we have in Cloud & Engineering.

 

Have more enquiries? Reach out to our Talent Team directly and they will be able to support you best.

Leave a comment on this blog: