Build an Azure Home Lab for Certs Without Overspending

Published:12 August 2026 - 12 min. read

Audit Active Directory for stale users, weak passwords, and other security risks with Specops Password Auditor.

A single virtual machine, nested three layers deep, standing in for an entire datacenter: would you let that anywhere near production? You’re about to build it anyway. The fastest way to learn what production Azure looks like turns out to be the thing you’d never risk running there. A home lab doesn’t need to be production grade to teach production grade lessons; it needs to be cheap enough to break on purpose and disposable enough that breaking it costs you nothing but time.

This guide builds that contradiction on purpose. You’ll carve a lab out of Azure’s free tier, then push past its limits with governed, non-free virtual machines that actually support nested virtualization. Along the way you’ll configure the same cost guardrails a real cloud team relies on: VM size restrictions, auto-shutdown schedules, and budget alerts, so a lab built for learning doesn’t quietly drain your credit card. By the end, you’ll have a working domain controller, a hybrid Arc connection, and a lab you can map directly to your next Azure certification exam.

Prerequisites

If you want to follow along hands-on, you’ll need:

  • An Azure account with billing enabled. The free account’s $200 credit and 12-month allowances get you started, but nested virtualization requires VM sizes outside the free tier, so keep a payment method on file.

  • Azure PowerShell installed locally, plus the Az.DevTestLabs module (Install-Module -Name Az.DevTestLabs) for the governance steps later.

  • An RDP client. Windows has one built in. macOS needs Windows App (Microsoft retired the standalone Remote Desktop client for macOS in favor of it), and Linux needs a compatible RDP client to reach your nested Hyper-V host.

  • Basic AD DS familiarity. You don’t need to already run a domain, but you should know what a domain controller does before you build one.

  • A resource group naming convention you’ll actually remember. Every command in this guide targets rg-homelab; swap it for your own name once, at the top.

  • Tested versions. This guide was verified against Azure CLI 2.80.0 and the Az.DevTestLabs module 1.2.0; run az version and Get-Module -ListAvailable -Name Az.DevTestLabs before you start.

Exact Tested Versions

This guide’s exact versions, in full: Azure CLI 2.80.0 and the Az.DevTestLabs PowerShell module 1.2.0, which pulls in Az.Accounts 5.5.2, each installed and run directly to confirm the commands below still work. The Azure Connected Machine agent (azcmagent) ships only for Windows and Linux, so it couldn’t be tested here; the current release listed on Microsoft’s agent release notes page is 1.66. Expect small command differences if you’re on an older release of any of these tools.

Know Your Free Tier Boundaries Before You Build

Before you touch a VM size that costs money, know exactly how much Azure hands you for free. The free account splits into three windows: a $200 credit good for the first 30 days on almost any service, a set of quota-capped services free for the next 12 months, and a smaller set that stays free indefinitely. The official free-account breakdown covers every quota, and those quotas reset monthly instead of rolling over.

Free Resource Monthly Allowance Duration
Windows/Linux VM (B1S, B2pts v2, B2ats v2) 750 hours 12 months
Managed disks Two 64 GB P6 SSDs 12 months
Blob storage (LRS Hot) 5 GB 12 months / always free
Azure SQL Database (S0) 250 GB 12 months / always free
Outbound data transfer 15 GB 12 months

What the Numbers Actually Mean

750 hours covers one B1S VM running nonstop for a full month (a 31-day month has 744 hours), or five B1S VMs split across 150 hours each. Either way, the free-tier VM sizes are enough to stand up a domain controller and a couple of member servers. They are not enough for the nested virtualization work later in this guide, and that’s a deliberate Microsoft limit on the B-series and A-series families, not an oversight you can work around.

Avoid the Free Tier’s Hidden Bills

“Free tier” doesn’t guarantee a $0 invoice. A handful of default settings quietly convert a free lab into a paid one:

  • Diagnostic telemetry. Turning on default diagnostics routes logs into Azure Log Analytics, and the free tier only covers 5 GB of ingestion a month. A chatty VM extension burns through that fast.

  • Orphaned public IPs. A static IP left attached to nothing still bills hourly. Delete it when you delete the VM, not after.

  • Outbound data transfer. The 15 GB free egress limit disappears quickly if you’re pulling container images or downloading ISOs into the lab.


Warning: Stopping a VM from inside the guest operating system does not stop the meter. Azure keeps billing compute until the VM is explicitly deallocated from the control plane, whether from the portal, az vm deallocate, or the auto-shutdown policy configured later in this guide. Storage charges for the attached disks continue either way.


Set a budget alert before you provision anything bigger than the free tier. It costs nothing to configure, and it’s the only setting in this guide that catches a mistake before it turns into an invoice.

Pick a VM Size That Actually Supports Nested Virtualization

The free-tier B-series and A-series VMs cannot run nested Hyper-V, because they don’t expose the hardware virtualization extensions to the guest operating system. To practice nested virtualization (running Hyper-V inside an Azure VM, which is how you’ll simulate a multi-node domain or a hybrid cluster) you need a VM family built for it.

VM Family Optimized For Supports Nested Virtualization
B-series, A-series (free tier) Burstable, low-cost No
Dv3 / Dv4 / Dv5 and v6 variants General purpose Yes
Ev3 / Ev4 / Ev5 Memory optimized Yes
Fsv2 Compute optimized Yes
M-series Extreme memory and CPU Yes

For a single nested host running a domain controller and a couple of L2 guests, Standard_D4s_v5 (4 vCPUs, 16 GB RAM) is a reasonable starting point.

Build the Host VM

Confirm the size is available in your region, then create the host with the security type set explicitly:

az vm list-skus --location eastus --size Standard_D4s_v5 --output table

az vm create \
  --resource-group rg-homelab \
  --name vm-hyperv-host \
  --image Win2022Datacenter \
  --size Standard_D4s_v5 \
  --security-type Standard \
  --admin-username azadmin \
  --admin-password '<STRONG_PASSWORD>'

--security-type Standard is the line most nested-virtualization walkthroughs skip, and it’s the one that breaks the setup. Newer Windows Server images default to Trusted Launch, and Trusted Launch does not expose the hardware virtualization extensions the guest OS needs. Microsoft’s own nested virtualization troubleshooting guide (linked later in this guide, in the section on building the internal switch) says it in exactly these words: “By default, the security type is Trusted launch virtual machines that doesn’t support nested virtualization. If you set the security type to Trusted launch virtual machines, and attempt to add server roles on the Rescue VM, you’ll encounter the following error message: Hyper-V cannot be installed because virtualization support is not enabled in the BIOS.” Install the Hyper-V role on a Trusted Launch VM and you’ll hit that exact message, which has nothing to do with your BIOS.


Pro Tip: Pull <STRONG_PASSWORD> from Azure Key Vault (az keyvault secret show) instead of typing it on the command line. It keeps the value out of your shell history, and it’s the same pattern real provisioning pipelines use.


Turn On Nested Hyper-V Inside the Host VM

RDP into the host VM, then enable Hyper-V from an elevated PowerShell session:

Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart

The VM reboots once the role installs. After it’s back, build the internal network your nested VMs will share. Without it, your L2 guests have no path to each other or to the internet:

New-VMSwitch -Name "NestedSwitch" -SwitchType Internal
New-NetNat -Name "NestedNAT" -InternalIPInterfaceAddressPrefix "192.168.0.0/24"

New-VMSwitch creates the internal network inside the host. New-NetNat gives that network a route out through the host’s own NIC, the same reverse-NAT pattern Microsoft documents for nested Azure VMs. Every nested VM you create from here gets an adapter on NestedSwitch and an address in the 192.168.0.0/24 range.

Expect a real performance cost. Published nested-virtualization benchmarks report CPU-bound overhead in the 10 to 20 percent range compared to bare metal, and I/O-heavy work loses even more, because every I/O call crosses two layers of translation instead of one. Provisioning the host on Premium SSD storage instead of Standard HDD, and keeping the nested guest count small, recovers most of that gap.

When the Hyper-V Role Refuses to Install

If Install-WindowsFeature fails with a message about virtualization support not being available in firmware, the host VM’s security type is the first thing to check, not the physical hardware under Azure’s own fabric. A VM created with the default --security-type TrustedLaunch (or no flag at all, on images where Trusted Launch is now the default) will fail here even though the underlying Azure host fully supports nested virtualization. Recreate the VM with --security-type Standard rather than hunting for a BIOS setting that doesn’t exist in a cloud VM.

Nested virtualization layers

Govern the Lab With Azure DevTest Labs

Once you’re running billable VM sizes, self-discipline is not a cost control strategy. Azure DevTest Labs wraps your subscription in policies that stop you, or anyone else with access, from provisioning something expensive by accident.

Two policies matter most for a solo home lab:

  • Allowed VM sizes. Restrict the lab to sizes you’ve already validated for nested virtualization, such as Standard_D4s_v5, and lock out M-series instances that can run hundreds of dollars a day.

  • VMs per lab. Cap the total VM count so a forgotten deployment loop can’t spin up ten hosts overnight.

You can configure both from the lab’s Configuration and policies blade in the portal, or script them with the same Az.DevTestLabs module you installed in Prerequisites. There is no reason to click through the portal every time you rebuild the lab. Set-AzDtlAllowedVMSizesPolicy and Set-AzDtlVMsPerLabPolicy cover the two policies:

Set-AzDtlAllowedVMSizesPolicy -LabName "lab-azurehomelab" -ResourceGroupName "rg-homelab" -VmSizes "Standard_D4s_v5" -Enable
Set-AzDtlVMsPerLabPolicy -LabName "lab-azurehomelab" -ResourceGroupName "rg-homelab" -MaxVMs 3 -Enable

-VmSizes takes the exact size strings you validated earlier, so Standard_D4s_v5 is the only entry unless you’ve tested others. -MaxVMs 3 is enough headroom for the host plus two nested guests without leaving room for a forgotten loop to spin up a tenth VM overnight. Auto-shutdown, the policy most likely to save you money, uses the identical scripting pattern: covered next.

DevTest Labs policy flow


Key Insight: The governance work in this section isn’t a detour from certification prep. Allowed VM sizes, per-lab quotas, and auto-shutdown scheduling sit inside the AZ-104 exam’s cost management domain. Configuring them here is the practice.


Reuse the Lab Without Rebuilding It

Once the lab exists, a formula saves you from re-entering the same base image, size, and network every time you claim a new VM. Formulas are just saved defaults, and artifacts go a step further: they’re scripts that run automatically after provisioning, installing tools like Git or the Azure CLI on a fresh guest without you RDPing in first. Neither is required to follow this guide, but both turn a one-time lab into something you can rebuild in minutes the next time you sit down to study.

Schedule Auto-Shutdown Before It Costs You

Auto-shutdown is the setting most likely to save you money in this entire build. Once it’s on, your lab’s VMs deallocate at a set time every day, whether you remembered to log off or not.

Set it once with the Az.DevTestLabs module instead of clicking through the portal every time you spin up a new lab:

Set-AzDtlAutoShutdownPolicy -ResourceGroupName "rg-homelab" -LabName "lab-azurehomelab" -Enable -Time "19:00"

Enabled labs send a notification 30 minutes before shutdown if you configure a webhook or email address, which gives you a chance to postpone the shutdown mid-lab. Decide upfront how strict you want the policy: users can fully opt out of the schedule, adjust the time but not disable it, or have no control at all. For a solo lab, “adjust but not disable” is the setting that stays out of your way without leaving a loophole big enough to forget through.

Build a Domain Controller Worth Practicing On

Your nested Hyper-V host is now a lab platform, not just a VM. Create an L2 guest from Hyper-V Manager (or New-VM from PowerShell), install Windows Server on it, then promote it to a domain controller:

Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
Install-ADDSForest -DomainName "lab.local" -InstallDns `
    -SafeModeAdministratorPassword (ConvertTo-SecureString "<STRONG_PASSWORD>" -AsPlainText -Force)

Install-ADDSForest reboots the VM automatically once the forest finishes provisioning. Give it a few minutes, then confirm the domain is live:

Get-ADDomain

A working lab.local domain unlocks the exercises that move the needle for AZ-104: group policy, DNS troubleshooting inside a real forest, and conditional access testing against a hybrid identity. None of that is possible on a single free-tier VM with no domain to join.

If Get-ADDomain returns nothing, check DNS before you check anything else. Install-ADDSForest configures the VM’s own network adapter as the primary DNS server for the new forest, so a nested VM that still points at a router-assigned DNS address, or at the internal NAT gateway instead of itself, will report a domain that technically exists but can’t be located. Run Get-DnsClientServerAddress on the domain controller and confirm it points to its own IP before you troubleshoot anything more exotic.

Extend the Lab Into Hybrid With Azure Arc

A domain controller running inside a nested VM is still, from Azure’s perspective, invisible infrastructure. Azure Arc closes that gap by projecting any server, on-prem or nested, into the Azure Resource Manager plane as if it were a native Azure resource.

Confirm your setup meets the Azure Arc prerequisites: network connectivity and the Azure Connected Machine Onboarding role. Then install the Connected Machine agent inside your nested domain controller VM and register it:

azcmagent connect --resource-group "rg-homelab" --tenant-id "<TENANT_ID>" --location "eastus" --subscription-id "<SUBSCRIPTION_ID>"

Once connected, the VM shows up in the Azure Portal next to your cloud resources, with the same Azure Policy, RBAC, and Resource Graph queries you’d use on a native Azure VM. Connect a nested Kubernetes cluster the same way, and Arc adds GitOps through Flux on top, so a change pushed to a Git repo rolls out to your nested cluster the same way it would to a fleet of production clusters.

If you’re simulating a locked-down corporate network alongside the domain controller, route the Connected Machine agent’s traffic through the Azure Arc Gateway instead of opening firewall rules for individual Azure service endpoints. The gateway consolidates that traffic through one relay point, which is closer to how a real network security team would actually approve an Arc rollout than “allow outbound to forty different Microsoft hostnames” ever is.

Enable Only What You’re Practicing

Core control plane features (inventory, tags, RBAC, and unlimited Kubernetes cluster connections) are free. The add-ons bill per server per month, per the official Azure Arc pricing page:

Add-On Monthly Cost
Azure Update Manager $5.00
Azure Policy Guest Configuration $6.00
Microsoft Defender for Servers (Plan 1) $5.00
Azure Monitor Analytics Logs Billed per GB beyond 5 GB free

If you’re prepping AZ-305 hybrid design scenarios, Azure Policy Guest Configuration is worth the $6 a month. If you’re only confirming Arc connectivity works, skip the add-ons entirely and rely on the free control plane.

Cloud vs hybrid Arc lab

Map the Lab to AZ-900, AZ-104, and AZ-305

Every piece of this lab maps to a specific certification objective, which most home-lab guides skip entirely:

Exam What You Just Practiced Why It’s Tested
AZ-900 Free tier billing, budget alerts Fundamentals covers cost management concepts, not just terminology
AZ-104 VM sizing, DevTest Labs policy, auto-shutdown, AD DS The administrator exam’s cost management and identity domains track closely to this build
AZ-305 Nested virtualization tradeoffs, Arc hybrid design The architect exam tests judgment about when a hybrid pattern makes sense, which this lab forces you to reason through

If you’re studying for a specific exam, work backward from this table. Rebuild the sections that map to your exam and skip the ones that don’t. There’s no reason to configure Arc three weeks before an AZ-900 attempt.

Tear Down Before You Forget

Everything in this guide lives inside one resource group, so cleanup is one command:

az group delete --name rg-homelab --yes --no-wait

--no-wait returns control immediately instead of blocking your terminal while Azure deletes several VMs, disks, and network interfaces in the background. Confirm the group is actually gone before you stop watching for charges:

az group show --name rg-homelab

A ResourceGroupNotFound error means the teardown finished and the meter stopped. If the group still shows up, something (usually a locked resource or a disk snapshot) is holding the deletion open, and it’s worth checking the Activity Log before you assume the bill has stopped.

Keep the Lab Working for You

You don’t need this lab running every day to get value from it. The pattern that makes it worth rebuilding is the one you just used: free tier for the basics, a governed non-free VM size for anything requiring nested virtualization, auto-shutdown as the default rather than the afterthought, and a teardown command you actually run.

Pair the rebuild habit with structured practice instead of ad hoc tinkering. Microsoft’s own AZ-104 learning path maps to the same domains this lab just exercised, so working through it against a live domain controller and a real (if small) hybrid connection will stick longer than reading the objectives cold. Rebuild it before your next practice exam and tear it down the same afternoon. Do that consistently, and you’ll spend less on Azure this month than most people spend on a single certification retake.

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!