How Azure DevTest Labs makes nested ARM template deployments easier for testing environments

Acknowledgement: This post is contributed by Roger Best, Senior Software Engineer in Customer Success Team. He’s been working on a solution to help our customers to adopt Azure DevTest Labs.

The DevTest Labs team has recently added new functionality to handle nested ARM template (aka. Linked ARM templates) deployment in the test environments scenario.  I wanted to take some time and talk about how this works and what problem it solves for you.  For more information on DevTest Lab environments you can get more details in the announcement.

Nested Deployment? What’s the problem?

A nested deployment allows you to execute other Azure Resource Manager (ARM) templates from within a main ARM template. It enables you to decompose your deployment into a set of targeted, purpose-specific templates, which provides benefits in terms of testing, reuse, and readability. The article Using linked templates when deploying Azure resources provides a good overview of this solution with several code samples. However, the examples in this article have explicit hard coded Uri locations, which isn’t always the best option as there will be additional work maintaining the source templates.

Solving the Problem with Key Parameters

While you can create your own ARM template from scratch, I would recommend that you use the Azure Resource Group project in Visual Studio.  Using Visual Studio improves that ease with which development and debugging of the template.  When you add the nested deployment resource to the azuredeploy.json, Visual Studio adds several different items to make the template more flexible, including the subfolder with the secondary ARM template and parameters file, variable names within main template file, and two parameters for the storage location for the new files.  The _artifactsLocation and _artifactsLocationSasToken are the key parameters that the DevTest Labs is will use, but more on that later.

What Does it Mean with DevTest Labs?

If you’re not familiar how the DevTest Labs works with environments (ARM Templates), the article Create multi-VM environments and PaaS resources with Azure Resource Manager templates provides detailed information what you can do with it and how.  Simply speaking, your ARM templates are stored in the repository linked to the DevTest Lab. When the user creates a new environment with those templates, the files are moved into an Azure Storage container in the DevTest Lab.  To be able to identify and copy the nested files the DevTest Labs identifies the _artifactsLocation and _artifactsLocationSasToken parameters and copies the sub-folders up to the storage container then automatically inserts the appropriate location and Shared Access Signature (SaS) token for the new location into the parameters. With this, you don’t need to bother updating the URI parameter for testing when using DevTest Labs.

Nested Deployment Example

Here is a simple example of a nested deployment

"$schema": "",

"contentVersion": "",

"parameters": {

"_artifactsLocation": {

"type": "string"


"_artifactsLocationSasToken": {

"type": "securestring"


"variables": {

"NestOneTemplateFolder": "nestedtemplates",

"NestOneTemplateFileName": "NestOne.json",

"NestOneTemplateParametersFileName": "NestOne.parameters.json"},

"resources": [


"name": "NestOne",

"type": "Microsoft.Resources/deployments",

"apiVersion": "2016-09-01",

"dependsOn": [ ],

"properties": {

"mode": "Incremental",

"templateLink": {

"uri": "[concat(parameters('_artifactsLocation'), '/', variables('NestOneTemplateFolder'), '/', variables('NestOneTemplateFileName'), parameters('_artifactsLocationSasToken'))]",

"contentVersion": ""


"parametersLink": {

"uri": "[concat(parameters('_artifactsLocation'), '/', variables('NestOneTemplateFolder'), '/', variables('NestOneTemplateParametersFileName'), parameters('_artifactsLocationSasToken'))]",

"contentVersion": ""




"outputs": {}

The folder in the repository containing this template will have a sub-folder “nestedtemplates” with the files NestOne.json and NestOne.parameters.json. In the azuredeploy.json, the templateLink.Uri and parametersLink.Uri is a concatenation of the storage account parameter, the sub-folder variable, and the Shared Access Signature (Sas) Token parameter.

Project structure with nested ARM template

Figure 1: Project structure with nested ARM template

Additional folders can be added under the primary folder but not any deeper than a single level, this maintains consistence with how the Visual Studio project handles additional nested deployments.


Now you can deploy nested templates in your environments in Azure DevTest Labs.  All that is needed is to have a nested template URI that points to a location under the _artifactsLocation location and the _artifactsLocationSasToken to allow for access to the files.


Roger BestRoger Best, Senior Software Engineer

Roger is part of the Visual Studio and .NET engineering team focused on Visual Studio and Azure customers.  He has been at Microsoft for 19 years, focusing on developer technologies for the past decade or so.  In his spare time, he watches too many movies, and tries to survive triathlons.

Comments (2)

  1. Mike Kiser says:

    Hi Roger, Great article. So I can use a VS project to include the nested files so that I don’t have to use the uri (or Linked Template )? Do you have an example of VS code from your article above? That would be awesome. Thanks! Mike

    1. I’m assuming that you are talking about an VS – Azure Resource Group project. You can include the nested files, but if you add the nested files manually you will need to change the files build action to content. Select file, Alt-Enter, change Build Action from None to Content. If you use the JSON Outline editor for the azuredeploy.json, and add a new “Nested Deployment” it will add the resource, the files with appropriate properties into the project, and set the UploadArtifacts for the Deploy-AzureResourceGroup.ps1.

Skip to main content