In this post I want to show you what I think it’s the best way to setup VSTS working with Azure Resource Manager Templates.


At the customer I am currently working for, we are setting up a new Azure Big Data ingestion environment and we wanted to do it using the Infrastructure as Code approach. With Azure this obviously goes with ARM Templates.

For source control, build and deployment we use Visual Studio Team Services (VSTS).

About VSTS, Build and Release Management

I have seen different setups with VSTS, some of them where the deployment take place from the build, or directly in Release Management without a build.

My approach is to have a clear separation of concerns between the Build and the Release Management.
The Build is for compiling, (Unit) Testing and creating artifacts for the deployment.
The Release Management’s responsibility is for deploying the artifacts created during the Build process.

Let’s begin

For this post I’m using ARM Linked Template, and the templates will create a Storage Account, an App Service Plan, an App Service and an Application Insight Resources.

Here are the template files I have used:


The main template is azuredeploy.json (1), which uses one of the parameter files (2) with the environment specific settings, and calls the linked template files (3) for creating the resources.

For this post I linked the GitHub sources to the Build.


1. Setup

I have defined a Buid variable called environment which I will use during the build for selecting the right template parameter file.

The customer I am working for is using a DTAP environment also in Azure, so every Resource Group have a suffix with the environment name in it.
Like: BlogOlandese-d, BlogOlandese-t, etc..

The parameters differs for each environment, that’s why we define this variable for selecting the right parameters (see later in this blog post).

2. AzureBlob File Copy Task

Because we are using an ARM linked template we need to upload the linked files to an Azure Blob Container.

From the Microsoft Documentation:
The Resource Manager service must be able to access the linked template. You cannot specify a local file or a file that is only available on your local network for the linked template. You can only provide a URI value that includes either http or https.

For this we use the Azure File Copy Task and I set it up like this:

Obviously there must be an existing storage account available, and I upload the files to a specific container.
In the output section I have defined two variables: storageURI and storageToken where the URI and tokens generated from this task will be saved, we will need them for the next step.

3. Azure Resource Group Deployment Task

The next task is the Azure Resource Group Deployment Task, which in this case the naming is not right, because we don’t want to deploy the template, instead, we want only validate it.
Luckily enough this task permits also to do the validation.

In this step after selecting the Azure Subscription, we select “Create or Update Resource Group” (1), we provide the Resource Group Name (2), for this I use the variable defined in Setup step.
Then we provide the Azure location and we provide the main template azuredeploy.json (3).
For the parameter file (4) we use again the Build variable $(environment) for selecting the right environment parameter file.

The parameters files are named like this:
azuredeploy.parameter.d.json, azuredeploy.parameter.t.json etc…

Then we need to provide some extra parameters (5) using the output variables defined in the Azure File Copy Task (storageURI, storageToken). This are needed because in the template we use the _artifactsLocation and _artifactsLocationSasToken parameters to build the storage URL to the files.

The container is not anonymous accessible, so to get its content we need a SAS Token.

And probably the most important setting (6) in this step: as Deployment Mode we select “Validation Only“.
This will do a syntax/schema check of the ARM Template without deploying the resources.
Unfortunately the validation doesn’t do much more, but still it’s better than nothing, at least we know if the build succeed that the ARM Template is syntactically correct.

4. Delete Resource Group if it is empty Task

The “Validation Only” mode has one little problem: even if it’s not deploying any resource, it creates the Resource Group specified and it doesn’t delete it if there is nothing in it:

That’s why I have created a VSTS Task which deletes the Resource Group only if it is empty.

If you are validating a template against an already existing Resource Group with resources in it this task obviously leaves everything intact, it will NOT delete the Resource Group.

5. Publish Build Artifacts Task

Then we publish the ARM Template files so that they can be used in Release Management.

The responsibility for the Build process stops here, we have taken the source files, validated them and created an artifact.

Release Management

1. Setup

In Release Management we create a new Release Definition and we link it to the Build Artifact we have previously created:

And we add four environments: Development, Test, Acceptance Production.

How many environments you define is up to your organisation deployment process.

As we did with the Build, we define an environment variable in every environment which we will use for the Resource Group naming and selection of the right environment parameter file.

2. AzureBlob File Copy Task

The first task is again to copy the Linked Resource Template files to an Azure Storage Container, the setup is quiet the same as we did in the Build but we change the source (1) to the the Build Artifact, and the container name (2) just to keep the container for the build and the release separate.

 3. Azure Resource Group Deployment Task

In Release Management this task will be used as the name implies: deployment!

Also here we configure this step quiet the same as we did in the build, we change the source of the main template (1) and the parameter (2) file and pointing them to the Build Artifact.

But this time the Deployment Mode (3) will be either “Incremental” or “Complete“, both of this options will deploy the resources.

Check the documentation about the differences between the Incremental and Complete deployment mode.

And finally we will have our resources in Azure:


In this blog post we used linked templates, the same can be accomplished using single files templates, then there’s no need to upload the files to Azure Storage.

I wanted to show you how the Build and Release Process with ARM Templates can be separated, keeping the responsibilities for building, validating and artifact creation in the Build flow and the deployment in the Release Management flow.