In the past, I wrote about an article on how to improve development as well as CI / CD pipelines with ARM-Templates. Those seem to be quite successful. Even though, I am sure everybody has it’s own opinion about some of the details I take the opportunity to lay out my current opinion to provide some solutions to problems I had or ideas where I thought that they could improve the quality of your pipeline in regards to deliver value. I will write a serious of articles that give you some tips. So let’s get right into it.
Once I had one idea. Generally, if you want to improve the quality of your code usually you write unit tests. With ARM-Templates and Pester this is possible. You can read an article from Amine Charot about it. He suggests using Pester to test not only syntax but also to check if you have the right structure in your ARM-Template (e.q. right schema or if the expected resources are included).
He mentions that you can test your template without deploying it. But I am asking: “Why not deploying it as well?”. We could just deploy our written ARM templates as part of ensuring quality.
There are just some things we need to make sure:
- Ensure that the resource names are unique
- create a resource group with a unique name and destroy it after you are finished
- If you have Azure Policies in place make sure you have a subscription for these very short-lived deployments
- If you deploy resources that would bill you costs immediately, then you should not create them (e.g. Azure App Service Certificates)
How could it basically look like? See the screenshot below to get an idea.
Let’s go through the main parts. It is actually simple if you at least know how to generally deploy ARM-Templates with Azure Pipelines:
First, generate a unique prefix for each resource name. This could be a GUID. Because of name restrictions you probably have to cut the GUID. It would not be 100% unique but for most cases enough. I in my case used a short PowerShell script to generate it and saved it into a pipeline variable, which I create on the spot. Below you can see the script I used.
$guid = New-Guid $v = [string]$guid $v = $v.Replace("-", "") $v = $v.substring(0, 6) echo "##vso[task.setvariable variable=randomGuid]$v"
You could also use this to randomize your resource group name. Since this is only a very short lived deployment you maybe want to have a unique resource group name. Also I delete this group by default at the end anyways.
Second, you just deploy all the resources that you need, but in every place where you need the unique prefix, you can use the created variable “randomGuid”. For example, when we look at the parameters I use for creating an Azure Function, the template parameter I override in the deploy task, could look like this.
Third, destroy the resource group (see screenshot below) after you are finished. But this task should always run, no matter if it succeeds or fails. Because often you deploy templates partially and you don’t want to leave anything behind. For this, you need to use the “Custom condition” option that you can use which each task. Below you see the custom condition which in my case should only run if my variable “KeepDeployment” is set to zero. This variable is by default zero. Which means I can choose on manual build to leave the resource if I wanted to check some things.
So just to make it more complete for you. I will add the full YAML code of the stage where I make the test deployment in my build pipeline.
Overall you would have the possibility to improve also the quality of your infrastrastructure by deploying it in your build pipeline. But there are several things every body needs to take into account and check for them selves like
- What are the additional costs?
- How much longer are the build when they are deployed with each CI triggered build (or should it be a nightly build?)
- Should you use a seperate subscription as a sandbox and possibly with additional policies or rules?
- How can you reuse the configuration? Now you deploy something in build that you would deploy in a very similar way in the release pipeline (maybe use task groups?)
- Should you use this build only as part of a pull request policy possibly?
Nevertheless, there is quite some potential within this to improve your IaC quality before releasing it to any environment.
Also published on Medium.