Azure ARM Templates – How to embed full scripts in your JSON templates!

Earlier today a colleague and I discovered a pretty neat trick when dissecting a broken ARM template; we learned you can encode complete scripts and embed them in your templates. This post will explain how to do so. First, some assumptions:

  • You have a Linux/Unix based machine available (terminal on Mac works fine, as does Bash on Windows 10)
  • You are familiar with JSON and ARM templates
  • You are familiar with shell scripts on some level

Using base64 and gzip you can encode and decode strings, which can then be used in your templates. Here’s an example:

The above output says, “This is a test” without any quotations. To get that output, from your terminal, you would type:

The above command takes your string, uses gzip to compress it, and base64 to binarily encode it. The output you receive should be similar to the one above. To decode you would type a similar command, but in reverse:

Like the encoding command, you’re taking your binary base64 string, decoding it, and decompressing the output using gunzip. Note the ‘-D’ switch in your base64 – that tells base64 to decrypt your string from binary data in ASCII string format to standard output.

Let’s say you have a file you want to compress and encoding. To do so, you would cat the file, pipe the output to gzip to compress, and another pipe to base64 to encoding. Here are two examples:

or

Now, the next question is, “How do I use that string in my ARM template?”  The answer is you take the output provided and use that in your custom data section. Be sure to use the ‘\n’ (no quotes) to specify the new line character after the end of the output string. Here’s an example:

As you can see, the example specifies base64 binary content and tells us our data is encoded using gzip. After each section, we see the ‘\n’ to specify a break in our custom data. When the template deploys, the encoded script/command used will be decrypted and decompressed on the fly, and then either copied to the location or executed accordingly. You will want to update your template file as necessary to reference the appropriate paths and variables of course, but the above gives you a general example.

To view a complete example, you can check out the JSON template I updated here – specifically lines 945 and 1181.

Reminder: All of my posts are provided "AS IS", imply no warranties, and confer no rights or special privileges. Use of included postings, code samples and other works are subject to the terms specified at Microsoft. For more information, click here.

Comments 3

  • One quibble: base64 encodes; it doesn’t encrypt. It’s not human-readable, but it’s also not secret: anybody with access to a base64-compatible utility can decode it back to human-readable text. If you need to transmit confidential information, base64 is NOT the answer!

    I know _you’re_ aware of the difference, but all of your readers might not be. Sorry to be a pedant.

    • Thank you, Marc! You are not a pedant, I can be pretty pedantic myself when it comes to this stuff. Yes, I was trying to figure out the best way to word it so my readers understand. I realize I went back and forth with the verbiage so I have corrected the post per your comment. Thanks again!

  • Thanks! Love your blog – keep’em coming!

Leave a Reply

Your email address will not be published. Required fields are marked *