Build and Lint Bicep Codes within CI/CD Pipelines: GitHub Actions & ARM Template Toolkit
Tags: armttk, bicep, githubactions, testing
Published: 2020-10-02 00:01:45

---
title: "Build and Lint Bicep Codes within CI/CD Pipelines: GitHub Actions & ARM Template Toolkit"
published: true
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/xrekdik5m5ervci775c2.png
description: "This post shows how to validate ARM templates generated by Bicep using ARM TTK and integrate with GitHub Actions workflow."
tags: armttk, bicep, githubactions, testing
canonical_url: https://devkimchi.com/2020/09/30/github-actions-and-arm-template-toolkit-to-test-bicep-codes/
series: Project Bicep, ARM Template Toolkit and GitHub Actions
---

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][post pester 1] and [#2][post pester 2], using [Pester][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][post prev], I introduced the [Project Bicep][gh bicep] that build ARM templates way easier. Throughout this post, I'm going to discuss [ARM Template Toolkit (ARM-TTK)][az arm ttk] to lint and validate the templates, and how this process can be applied to our CI/CD pipelines using the [GitHub Actions][gh actions] workflow.

> The sample Bicep code used in this post can be downloaded from this [GitHub repository][gh sample].


## ARM Template Toolkit (ARM TTK) ##

[ARM Template Toolkit(ARM TTK)][az 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][gh arm ttk], 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.

![][image-01]

> In order to use ARM TTK, I'd recommend cloning the [GitHub repository][gh arm ttk] rather than downloading the artifact linked from the [official document][az arm ttk] 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.

{% gist https://gist.github.com/justinyoo/0acf46566623e346553b5dabe5c1fe5b file=01-bicep-build.ps1 %}

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.

{% gist https://gist.github.com/justinyoo/0acf46566623e346553b5dabe5c1fe5b file=02-run-arm-ttk.ps1 %}

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

![][image-02]

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

![][image-03]


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

* [Bicep Build][gh actions bicep]
* [ARM TTK][gh actions arm ttk]

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

{% gist https://gist.github.com/justinyoo/0acf46566623e346553b5dabe5c1fe5b file=03-github-actions.yaml %}

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][post pester 1] and [#2][post pester 2].

---

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


[image-01]: https://sa0blogs.blob.core.windows.net/devkimchi/2020/09/github-actions-and-arm-template-toolkit-to-test-bicep-codes-01.png
[image-02]: https://sa0blogs.blob.core.windows.net/devkimchi/2020/09/github-actions-and-arm-template-toolkit-to-test-bicep-codes-02.png
[image-03]: https://sa0blogs.blob.core.windows.net/devkimchi/2020/09/github-actions-and-arm-template-toolkit-to-test-bicep-codes-03.png

[post prev]: /azure/project-bicep-sneak-peek-the-arm-template-dsl-3np0
[post pester 1]: https://devkimchi.com/2018/01/22/testing-arm-templates-with-pester/
[post pester 2]: https://devkimchi.com/2018/07/12/testing-arm-templates-with-pester-2/

[gh sample]: https://github.com/devkimchi/LiveStream-VM-Setup-Sample/blob/main/bicep/azuredeploy.bicep
[gh bicep]: https://github.com/Azure/bicep
[gh arm ttk]: https://github.com/Azure/arm-ttk
[gh actions]: https://github.com/features/actions
[gh actions bicep]: https://github.com/marketplace/actions/bicep-build
[gh actions arm ttk]: https://github.com/marketplace/actions/arm-template-toolkit-arm-ttk

[pester]: https://github.com/pester/Pester

[az arm ttk]: https://docs.microsoft.com/azure/azure-resource-manager/templates/test-toolkit?WT.mc_id=devto-blog-juyoo
[az arm template]: https://docs.microsoft.com/azure/azure-resource-manager/templates/overview?WT.mc_id=devto-blog-juyoo
[az arm template manual]: https://github.com/devkimchi/LiveStream-VM-Setup-Sample/blob/main/azuredeploy.json
[az arm template bicep]: https://github.com/devkimchi/LiveStream-VM-Setup-Sample/blob/main/bicep/azuredeploy.json
[az arm function providers]: https://docs.microsoft.com/azure/azure-resource-manager/templates/template-functions-resource?WT.mc_id=devto-blog-juyoo#providers
[az arm validation providers]: https://docs.microsoft.com/azure/azure-resource-manager/templates/test-cases?WT.mc_id=devto-blog-juyoo#use-hardcoded-api-version

[az bicep install]: https://github.com/Azure/bicep/blob/master/docs/installing.md