Best Practices for setting up Azure DevTest Labs artifact / template development environment

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.

One of the features of DevTest Labs is the ability to easily apply custom tools and machine configurations.  Artifacts within DevTest Labs are used to deploy and configure the environment during or after the VM has been provisioned. You can create custom artifacts and add those into the lab by connecting to the Git repository. One of the benefits of having custom artifacts is the ability to have automated environment creation that includes internal products/tools.  There are challenges to set up development environment for your custom artifacts, but most can be avoid using the following recommendations. For suggestions on authoring or troubleshooting custom artifacts, please check out Tips and tricks on Azure DevTest Labs artifacts development and debugging.

High-level Principle

A key principle of software development is isolation, being able to make changes without effecting the system while in development.  Use it as the guiding principle of the following recommendations will improve the experience of using DevTest Labs. So how does it apply when setting up an artifact/template development environment with DevTest Labs to allow continuous development while limiting the down time?

Setting up the Repository(ies)

The default configuration for a DevTest Lab is that the artifacts come from the public repository.  To add custom artifacts, a repository will need to be added to the lab.  Most commonly the “master” branch is connected to the production lab, it’s not required but will make the code flow is not recommended.  The next step is to create a “development” branch off the master branch, which will help to enable the appropriate code flow that allows the pulling (generating a pull request) of artifacts and templates from the development branch to master.  In larger environments, additional branches under the development branch would appear for individual developers, teams, or different work items, depending on the DevTest Lab owners’ preferences.

Set up Development DevTest Lab(s)

Setting up a secondary “Testing/Staging” DevTest lab for developing and testing custom artifacts/templates is strongly recommended (Check out this article if you want to Automate Adding an Artifact Repository in Azure DevTest Labs).  At a minimum, this lab will be connected to the “development” branch which will allow developers to check-in changes to artifacts or templates and complete whatever process before setting up a pull request to the master branch.  Additional branches that are under the development branch can be added to the same development lab as the repository branch information is part of the artifact deployment.  In larger environments, following the flow of “development – testing/staging – production” will improve efficiency.  In that model, the “development” lab is the testing/staging and additional lab(s) will need to be created for the branches below the development branch.  The following diagrams show the two different configurations.

Single Development DevTest Lab

Figure 1: Single Development DevTest Lab

Separate Development and Test/Staging Labs

Figure 2: Separate Development and Test/Staging Labs

Setting up user roles for the different labs

The “Principle of least privilege” is the key when setting up user roles in the different labs.  In the production lab there should be a minimal set of owners, all users should be in the “DevTest Labs User” role which allows VM manipulation and applying artifacts.  Additional access may be required when creating labs or customizing the artifact repositories.  The ability to create custom roles has the greatest control and clarity of access. Below is a code sample of how to create a custom role based on the “DevTest Labs User” and adds the capabilities to add or modify repositories to the lab.


$policyName = "<Policy Name>"

$subscriptionID = "<Subscription ID>"


#Create custom role that extends the DevTest Labs User policy.

$policyRoleDef = (Get-AzureRmRoleDefinition "DevTest Labs User")


$policyRoleDef.Id = $null

$policyRoleDef.Name = $policyName

$policyRoleDef.IsCustom = $true




$policyRoleDef = (New-AzureRmRoleDefinition -Role $policyRoleDef)


#Assign policy/role to a user

$user = Get-AzureRmADUser -Mail "<>"

New-AzureRmRoleAssignment -ObjectId $user.Id -RoleDefinitionName $policyName -Scope /subscriptions/$subscriptionID


If you have any feedback for DevTest Labs, please submit your idea or vote others at its feedback forum.

If you have any questions, please check out the MSDN forum.


Hope this helps.

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 18 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 (0)

Skip to main content