3 min read

GitHub Actions and ARM Template Toolkit for Bicep Codes Linting

Justin Yoo

Let's have a look at the Project Bicep and ARM Template Toolkit, and GitHub Actions for both.

Once we build an ARM template, we need to verify whether the template is written in a proper way or will be working as expected. I wrote a couple of blog posts, #1 and #2, using Pester for ARM Template validation. However, that approach required us to log in to Azure first, which was doable but less desirable. What if we can verify the template without having to log in to Azure?

In my previous post, I introduced the Project Bicep that build ARM templates way easier. Throughout this post, I'm going to discuss ARM Template Toolkit (ARM-TTK) to lint and validate the templates, and how this process can be applied to our CI/CD pipelines using the GitHub Actions workflow.

The sample Bicep code used in this post can be downloaded from this GitHub repository.

ARM Template Toolkit (ARM TTK)

ARM Template Toolkit(ARM TTK) offers consistent and standard ways of coding practices to build ARM templates with much more readability that includes:

  • Validating the author's intentions by eliminating unused parameters and variables,
  • Applying security practices like outputting secrets in plain text format, and
  • Using environment functions to provide constants like domain suffixes, rather than hard-coded values.

ARM TTK is written in PowerShell, as of writing this post, it's v0.3. As PowerShell supports cross-platform, ARM TTK can also run on Windows, Mac and Linux boxes.

In order to use ARM TTK, I'd recommend cloning the GitHub repository rather than downloading the artifact linked from the official document because the repository gets regularly updated in a fast pace.

Run ARM TTK against Templates

First of all, run the bicep CLI to build the ARM template.

bicep build **/*.bicep
view raw 01-bicep-build.ps1 hosted with ❤ by GitHub

Then, run the following PowerShell command. Please note that, if you want to test all ARM templates in a specific directory, there MUST be either azuredeploy.json or maintemplate.json in the directory; otherwise ARM TTK will complain it.

Test-AzTemplate -TemplatePath ./bicep
view raw 02-run-arm-ttk.ps1 hosted with ❤ by GitHub

The result after running ARM TTK might look like below. I've got my template using the old API version. For example, Azure Storage Account uses the API version of 2017-10-01, which is older than two years. It complains that I SHOULD use the newest version of 2019-06-01.

After fixing all the complaints and running ARM TTK again, it passes all the linting!

Run GitHub Actions for Bicep CLI and ARM TTK on CI/CD Pipelines

We've got all bicep CLI and ARM TTK working in our local machine. Let's run both bicep CLI and ARM TTK on CI/CD pipelines. There are two GitHub Actions for both.

After applying those actions to the CI/CD pipeline, it might look like the following:

name: ARM Template Build and Test
on: [ push, pull_request ]
jobs:
build_and_test:
name: Build and Test
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Run Bicep build
uses: aliencube/bicep-build-actions@v0.1
with:
files: '**/*.bicep'
- name: Run ARM TTK
uses: aliencube/arm-ttk-actions@v0.3
id: armtest
with:
path: ./bicep
- name: Show ARM TTK test result
shell: bash
continue-on-error: true
run: |
echo 'Results: ${{ toJSON(fromJSON(steps.armtest.outputs.results)) }}'
  1. All the .bicep files are compiled to ARM templates through the Bicep Build action (line #15-18).
  2. Lint those converted ARM templates through the ARM TTK action (line #20-24).
  3. Display the result generated from the ARM TTK action. As the ARM TTK action returns an output as a JSON object format, we can leverage the JSON object to generate test reports (line #26-30).

Now, by following this workflow, we can easily build the .bicep files and verify them. Then only passed templates can provision resources to Azure.

But, we should make sure one thing. Before running ARM TTK, the ARM template worked perfectly fine. However, ARM TTK complained that it was not compliant. It means that ARM TTK doesn't validate what the provisioning result will be, but do check the code quality. Therefore, to check whether the resources declared in the template will be provisioned or not, we still need other testing logic, discussed in the previous posts #1 and #2.


So far, we've set up the CI/CD pipeline with Bicep CLI and ARM TTK to build and verify the .bicep files. Can you play them around on your own pipelines?