Link ARM deployment to enable more customization

Mikhail Chatillon
3 min readFeb 20, 2018

--

I recently worked with Loriot, a Swiss startup providing long range infrastructure for IoT (using LoraWan). They wanted to create an IoT ingestion pipeline architecture that could be easily deployable in their own customers’ Azure subscription and connected to their own Loriot cloud service.
On Azure, you typically tackle this kind of problem with a technology called Azure Resource Manager (ARM) template. A template consists of a JSON file describing the desired component of an architecture, their configuration and connections. Most of Azure resource type can be deployed and customized easily this way. In a nutshell, an ARM template could be seen as a blueprint of a deployment that Azure will follow it to deploy a given architecture.
It is a great solution enabling packaging and redeploying an existing architecture in a rapid way. Diving deep into the bowel of this technology is out of scope on this article, but if it rises your interest you could find more information here.

The problem

Templates are great to deploy any Azure resource, however it won’t help you to personalize anything specific to a technology within a ARM element. For example, you will be able to create a SQL database in the ARM template very easily, however, it is impossible to create a table in your new database during template creation. Of course, you could create those quite easily with external scripts/tools but this would require an external component.
As our customer was looking for a turn-key solution requiring no customization step for his customers, this was no option for us and we had to find a way to create collections in CosmosDB and tables in SQL Server during at ARM deployment time.

Initial Thoughts

By reading more on the ARM templates I realized it was possible to reference linked templates outside the main template by using the Microsoft.Resources/deployments type as below. I realized that this element was simply issuing a HTTP GET request to the location specified in the templatelink URI element to fetch the external JSON file to deploy.

An element initating a call to an external linked template json

As there was a way to issue an HTTP GET from the ARM template deployment, I needed to find a way to easily create an endpoint during the deployment. This was an easy choice for me as I am a big fan of serverless due to its simplicity of usage. I decided then to create an HTTP triggered Azure function that could perform the additional setup steps by using the C# API for SQL database and CosmosDB. This Setup function would be deployed after the two databases have been deployed and be able to call their respective API thanks to connection strings set in the application settings.

App settings defining connection to the database within the Setup function

One does not simply…

However, having this linked ARM calling the Setup function in the main template gave an error. Indeed, in ARM template, expressions seem to be evaluated at the beginning of the template deployment. So when I use the following expression to put the function HTTP URL as the nested template URI, it fails as the function does not yet exist.

[listsecrets(resourceId(‘Microsoft.Web/sites/functions’, ‘function’, ‘Setup’),’2015–08–01').trigger_url]

… call non-existing elements

We managed to solve the issue by adding an additional level of indirection. The main template does not call directly the Setup function, but refers to an additional external template file that will in turn trigger the function. By using this trick, evaluation of the listsecrets expression will be delayed until the execution of the intermediary template, and the actual function app will be up and running at this time.

Using this trick enabled us to achieve our goal quite simply. I think it enables much more customization and set up steps during an ARM deployment. You could extend from this strategy to perform basically any action on elements having an external API and further customize your Azure deployment in an easy way. You can find the whole project and template here.

--

--

Mikhail Chatillon

Software Engineer at Microsoft in Switzerland. I love technology, video games and chocolate. Articles reflect my own opinion only.