2026-09-09 · 15 min read · Infrastructure Revamp

Mastering Azure DevTest Labs: An Essential Setup Guide for SMBs

Screenshot of Azure DevTest Labs dashboard showing virtual machines and policies, representing an Azure DevTest Labs setup guide.

For many small and medium-sized businesses (SMBs), managing development and testing environments can be a significant drain on resources. Inconsistent setups, forgotten VMs running overnight, and the time spent manually provisioning environments all contribute to inefficiency and escalating costs. This is where Azure DevTest Labs becomes an indispensable tool. It provides a self-service model for developers and testers to quickly spin up, manage, and tear down Azure Virtual Machines (VMs) and environments, all while enforcing robust cost controls and streamlining workflows.

This comprehensive Azure DevTest Labs setup guide from SkyCore Solutions will walk you through the process of establishing a secure, cost-effective, and highly efficient DevTest Labs environment. By the end of this guide, you will have a fully configured Azure DevTest Lab, complete with essential policies, a network integration, and your first provisioned VM, ready for your team to accelerate their development and testing cycles.

Prerequisites

Step 1: Prepare Your Azure Environment

Before deploying any new Azure service, it's best practice to create a dedicated resource group. This helps organize your resources, simplifies management, and makes it easy to delete all related resources when they are no longer needed, preventing lingering costs.

az group create \
  --name "SkyCore-DevTestLabs-RG" \
  --location "canadacentral"
New-AzResourceGroup `
  -Name "SkyCore-DevTestLabs-RG" `
  -Location "Canada Central"

Portal alternative: From the Azure portal, search for "Resource groups" > Select "Create" > Fill in Subscription, Resource group name (e.g., SkyCore-DevTestLabs-RG), and Region (e.g., Canada Central) > Click "Review + create" then "Create".

Run this to verify:

az group show --name "SkyCore-DevTestLabs-RG" --query name
Get-AzResourceGroup -Name "SkyCore-DevTestLabs-RG" | Select-Object ResourceGroupName

Step 2: Create the Azure DevTest Lab

Now, let's create the DevTest Lab itself. This is the central hub where all your development and testing VMs will reside. When creating the lab, it's crucial for SMBs to immediately enable and configure autoshutdown policies to prevent VMs from running unnecessarily and incurring costs overnight or on weekends.

az lab create \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --name "SkyCore-DevLab" \
  --location "canadacentral" \
  --autoshutdown-status Enabled \
  --autoshutdown-time 1900 \
  --autoshutdown-timezone "Canada/Eastern" \
  --autoshutdown-notification-status Enabled \
  --autoshutdown-notification-emails "devops@skycore.ca" \
  --tags Project=DevTest Environment=DevOps
New-AzDevTestLab `
  -ResourceGroupName "SkyCore-DevTestLabs-RG" `
  -Name "SkyCore-DevLab" `
  -Location "Canada Central" `
  -AutoShutdownStatus Enabled `
  -AutoShutdownTime 1900 `
  -AutoShutdownTimeZone "Canada/Eastern" `
  -AutoShutdownNotificationStatus Enabled `
  -AutoShutdownNotificationMail "devops@skycore.ca" `
  -Tag @{ Project="DevTest"; Environment="DevOps" }

Portal alternative: Search for "DevTest Labs" > Select "Create" > Fill in "Subscription", "Resource group" (SkyCore-DevTestLabs-RG), "Lab name" (SkyCore-DevLab), and "Location". On the "Auto-shutdown" tab, set "Enabled" to On, specify "Scheduled shutdown" time (e.g., 19:00) and "Time zone" (e.g., Canada/Eastern), and configure notifications. Finally, click "Review + create" then "Create".

Run this to verify:

az lab show --resource-group "SkyCore-DevTestLabs-RG" --name "SkyCore-DevLab" --query '{name: name, location: location, autoshutdownStatus: autoshutdown.status}'
Get-AzDevTestLab -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name "SkyCore-DevLab" | Select-Object Name, Location, AutoShutdownStatus
Common pitfall: Forgetting Autoshutdown!

The single biggest cause of unexpected Azure costs in DevTest environments is forgetting to shut down VMs. Even if you don't configure all policies initially, ensure autoshutdown is enabled from day one. It's the most effective immediate cost-saving measure for any Azure DevTest Labs setup guide.

Step 3: Configure Essential Lab Policies for Cost Control

With your lab created, the next step is to enforce more granular cost controls and governance. DevTest Labs policies allow you to define limits on VM sizes, the number of VMs a user can create, and the total number of VMs in the lab. For SMBs, these policies are critical for managing budget and preventing resource sprawl.

# Set policy for allowed VM sizes
az lab policy update \
  --lab-name "SkyCore-DevLab" \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --name AllowedVmSizesInLab \
  --properties '{"status": "Enabled", "threshold": "[ \"Standard_D2s_v5\", \"Standard_E2s_v5\" ]"}'

# Set policy for maximum VMs per user (e.g., 1 VM per developer)
az lab policy update \
  --lab-name "SkyCore-DevLab" \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --name MaxVmsAllowedPerUser \
  --properties '{"status": "Enabled", "threshold": "1"}'

# Set policy for maximum total VMs in the lab
az lab policy update \
  --lab-name "SkyCore-DevLab" \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --name MaxTotalVmsAllowed \
  --properties '{"status": "Enabled", "threshold": "5"}'
# Set policy for allowed VM sizes
$labName = "SkyCore-DevLab"
$rgName = "SkyCore-DevTestLabs-RG"
$allowedSizes = '[ "Standard_D2s_v5", "Standard_E2s_v5" ]'
Set-AzDevTestLabPolicy -LabName $labName -ResourceGroupName $rgName -Name AllowedVmSizesInLab -Status Enabled -Threshold $allowedSizes

# Set policy for maximum VMs per user
Set-AzDevTestLabPolicy -LabName $labName -ResourceGroupName $rgName -Name MaxVmsAllowedPerUser -Status Enabled -Threshold "1"

# Set policy for maximum total VMs in the lab
Set-AzDevTestLabPolicy -LabName $labName -ResourceGroupName $rgName -Name MaxTotalVmsAllowed -Status Enabled -Threshold "5"

Portal alternative: Navigate to your DevTest Lab > Under "Settings", select "Configuration and policies" > Under "Policies", click on each policy (e.g., "Allowed virtual machine sizes", "Virtual machines per user", "Virtual machines per lab") > Set "Status" to On and configure the specific limits > Click "Save".

Run this to verify:

az lab policy show --lab-name "SkyCore-DevLab" --resource-group "SkyCore-DevTestLabs-RG" --name AllowedVmSizesInLab --query '{name: name, status: status, threshold: threshold}'
az lab policy show --lab-name "SkyCore-DevLab" --resource-group "SkyCore-DevTestLabs-RG" --name MaxVmsAllowedPerUser --query '{name: name, status: status, threshold: threshold}'
az lab policy show --lab-name "SkyCore-DevLab" --resource-group "SkyCore-DevTestLabs-RG" --name MaxTotalVmsAllowed --query '{name: name, status: status, threshold: threshold}'
Get-AzDevTestLabPolicy -LabName "SkyCore-DevLab" -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name AllowedVmSizesInLab | Select-Object Name, Status, Threshold
Get-AzDevTestLabPolicy -LabName "SkyCore-DevLab" -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name MaxVmsAllowedPerUser | Select-Object Name, Status, Threshold
Get-AzDevTestLabPolicy -LabName "SkyCore-DevLab" -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name MaxTotalVmsAllowed | Select-Object Name, Status, Threshold
Pro tip: Use Formulas for Common VM Setups

For repeatable and consistent VM configurations, consider creating a "Formula" within your DevTest Lab. A formula is a base VM image with pre-installed software and settings. Users can then create VMs from this formula, ensuring everyone starts with the same environment. This significantly reduces setup time and ensures consistency across your dev/test teams.

Step 4: Add a Virtual Network (Optional but Recommended)

While DevTest Labs creates a default virtual network, for most SMBs, integrating your lab with an existing or new dedicated virtual network is highly recommended. This allows for better network isolation, controlled access to other Azure resources (like databases or storage accounts), or even hybrid connectivity back to your on-premises network. Note that associating a VNet directly via CLI during az lab create is not explicitly supported by the provided documentation; it's typically configured via the Azure portal during creation or added afterwards.

First, let's create a new virtual network and subnet if you don't have one already. If you already have a VNet, you can skip this step and use its details in the portal configuration.

# Create a new Virtual Network
az network vnet create \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --name "SkyCore-DevLab-VNet" \
  --location "canadacentral" \
  --address-prefix "10.0.0.0/16"

# Create a subnet within the VNet for DevTest Labs VMs
az network vnet subnet create \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --vnet-name "SkyCore-DevLab-VNet" \
  --name "DevLabSubnet" \
  --address-prefix "10.0.1.0/24"
# Create a new Virtual Network
New-AzVirtualNetwork `
  -ResourceGroupName "SkyCore-DevTestLabs-RG" `
  -Name "SkyCore-DevLab-VNet" `
  -Location "Canada Central" `
  -AddressPrefix "10.0.0.0/16"

# Create a subnet within the VNet for DevTest Labs VMs
Add-AzVirtualNetworkSubnetConfig `
  -Name "DevLabSubnet" `
  -AddressPrefix "10.0.1.0/24" `
  -VirtualNetwork (Get-AzVirtualNetwork -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name "SkyCore-DevLab-VNet") | `
Set-AzVirtualNetwork

Portal alternative (for associating VNet with Lab): Navigate to your DevTest Lab > Under "Settings", select "Configuration and policies" > Select "Virtual networks" > Click "+ Add" > Select the desired Virtual Network (e.g., SkyCore-DevLab-VNet) and its subnet (e.g., DevLabSubnet) > Click "Save". Alternatively, during lab creation, on the "Networking" tab, select your custom VNet and subnet.

Run this to verify (VNet and Subnet creation):

az network vnet show --resource-group "SkyCore-DevTestLabs-RG" --name "SkyCore-DevLab-VNet" --query '{name: name, subnets: subnets[].name}'
Get-AzVirtualNetwork -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name "SkyCore-DevLab-VNet" | Select-Object Name, @{Name='Subnets'; Expression={$_.Subnets.Name}}

Step 5: Provision a Virtual Machine within the Lab

With the lab and policies in place, it's time to create your first virtual machine. This VM will automatically inherit the policies defined for the lab, ensuring it adheres to your organization's cost controls and standards. For SMBs, using a public Marketplace image is the quickest way to get started.

az lab vm create \
  --lab-name "SkyCore-DevLab" \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --name "DevVM-001" \
  --image "MicrosoftWindowsDesktop:windows11-22h2-pro:win11-22h2-pro-g2:latest" \
  --size "Standard_D2s_v5" \
  --admin-username "devuser" \
  --admin-password "P@ssw0rdSkyCore!1" \
  --generate-public-ip true
New-AzDevTestLabVM `
  -LabName "SkyCore-DevLab" `
  -ResourceGroupName "SkyCore-DevTestLabs-RG" `
  -Name "DevVM-001" `
  -ImageName "MicrosoftWindowsDesktop:windows11-22h2-pro:win11-22h2-pro-g2:latest" `
  -Size "Standard_D2s_v5" `
  -AdminUsername "devuser" `
  -AdminPassword "P@ssw0rdSkyCore!1" `
  -GeneratePublicIp

Portal alternative: Navigate to your DevTest Lab > Click "+ Add" > On the "Choose a base" page, select your desired image (e.g., Windows 11 Pro, version 22H2) > On the "Basic Settings" tab, fill in "Virtual machine name", "User name", "Password", and select "Virtual machine size" > Click "Create".

Run this to verify:

az lab vm show --lab-name "SkyCore-DevLab" --resource-group "SkyCore-DevTestLabs-RG" --name "DevVM-001" --query '{name: name, size: size, provisioningState: provisioningState}'
Get-AzDevTestLabVM -LabName "SkyCore-DevLab" -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name "DevVM-001" | Select-Object Name, Size, ProvisioningState

Step 6: Automate VM Setup with Artifacts (Advanced)

Artifacts are powerful pre-packaged scripts or tools that can be automatically applied to a VM during or after its creation. They allow you to automate tasks like installing software, running configuration scripts, or deploying applications. This ensures consistency across your dev/test environments and reduces manual setup time. While the core DevTest Labs provides a public repository of artifacts, SMBs often benefit from creating their own private repositories for custom scripts and applications.

# Add a private Git artifact repository to your lab
az lab artifact-source create \
  --lab-name "SkyCore-DevLab" \
  --resource-group "SkyCore-DevTestLabs-RG" \
  --name "SkyCorePrivateArtifacts" \
  --display-name "SkyCore Private Artifacts" \
  --source-type GitHub \
  --uri "https://github.com/your-org/devtest-artifacts.git" \
  --folder-path "/artifacts" \
  --branch-ref "main" \
  --personal-access-token "YOUR_GITHUB_PAT"
# Add a private Git artifact repository to your lab
$pat = ConvertTo-SecureString "YOUR_GITHUB_PAT" -AsPlainText -Force
Add-AzDevTestLabArtifactSource `
  -LabName "SkyCore-DevLab" `
  -ResourceGroupName "SkyCore-DevTestLabs-RG" `
  -Name "SkyCorePrivateArtifacts" `
  -DisplayName "SkyCore Private Artifacts" `
  -SourceType GitHub `
  -Uri "https://github.com/your-org/devtest-artifacts.git" `
  -FolderPath "/artifacts" `
  -BranchRef "main" `
  -PersonalAccessToken $pat

Portal alternative: Navigate to your DevTest Lab > Under "Settings", select "Configuration and policies" > Under "Artifacts", select "Artifact sources" > Click "+ Add" > Fill in details for your Git repository (e.g., "Name", "Display Name", "Source type", "Git clone URI", "Branch", "Personal Access Token") > Click "Save". Once added, when creating a new VM, you can select the "Artifacts" tab and choose artifacts from your newly added repository.

Run this to verify:

az lab artifact-source show --lab-name "SkyCore-DevLab" --resource-group "SkyCore-DevTestLabs-RG" --name "SkyCorePrivateArtifacts" --query '{name: name, sourceType: sourceType, uri: uri}'
Get-AzDevTestLabArtifactSource -LabName "SkyCore-DevLab" -ResourceGroupName "SkyCore-DevTestLabs-RG" -Name "SkyCorePrivateArtifacts" | Select-Object Name, SourceType, Uri

When to bring in a consultant

While this Azure DevTest Labs setup guide provides a solid foundation for most SMBs, more complex scenarios can benefit significantly from expert guidance. Consider engaging SkyCore Solutions if you need assistance with:

Our team of Azure architects at SkyCore Solutions specializes in tailoring cloud solutions to your unique business needs, ensuring you get the most out of your Azure investment.

Book a free consultation

References