A hand-built golden image is a time bomb: it drifts, nobody remembers exactly how it was made, and patching means clicking through a VM at midnight. Automating image builds with Azure Image Builder and Bicep turns the image into versioned, repeatable code.
Why manual images fail at scale
- Drift — small manual tweaks accumulate; the next image is subtly different.
- No history — you can’t diff or roll back a click-built VM.
- Slow patch cadence — manual rebuilds are painful, so they happen rarely, so hosts fall behind.
- Bus factor — the process lives in one person’s memory.
The automated pipeline

The modern pattern combines three pieces:
- Azure VM Image Builder (AIB) — a managed service that builds an image from a source plus a list of customisation steps.
- Azure Compute Gallery — versioned image storage with multi-region replication, so host pools pull a specific image version.
- Bicep / IaC + a pipeline — to define the build template and run it on a schedule (e.g. monthly, post-Patch-Tuesday).
The outcome
Every image is a numbered version in the gallery, built from code you can review and re-run. Patching becomes ‘run the pipeline’, and rollback becomes ‘point the host pool at the previous version’.
What goes in the build template
An AIB template typically starts from a marketplace multi-session Windows image and layers your customisations:
- Windows Updates (so each build is freshly patched).
- Core applications and the FSLogix agent.
- AVD-specific optimisations and the multi-session tuning.
- Security baseline and your AV / management agents.
- Sysprep/generalise at the end so the image is reusable.
A minimal Bicep shape
You don’t need much to get started — an image template resource pointing at a source, a set of customisers, and a distribution target (the compute gallery):
resource imageTemplate 'Microsoft.VirtualMachineImages/imageTemplates@2022-07-01' = {
name: 'avd-win11-multisession'
location: location
identity: { type: 'UserAssigned', userAssignedIdentities: { '${aibIdentityId}': {} } }
properties: {
source: {
type: 'PlatformImage'
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-11'
sku: 'win11-23h2-avd'
version: 'latest'
}
customize: [
{ type: 'WindowsUpdate', searchCriteria: 'IsInstalled=0' }
{ type: 'PowerShell', name: 'InstallApps', scriptUri: appsScriptUri }
]
distribute: [
{
type: 'SharedImage'
galleryImageId: galleryImageDefinitionId
runOutputName: 'avd-image'
replicationRegions: [ location ]
}
]
}
}Pair AIB with PowerShell
Keep the heavy lifting (app installs, tuning) in versioned PowerShell scripts that AIB calls. The Bicep defines structure; the scripts define content. Both live in source control.
Wiring it into a release cadence
Run the template from a pipeline (Azure DevOps or GitHub Actions) on a schedule. A healthy rhythm: build a fresh, patched image monthly after Patch Tuesday, publish it as a new gallery version, validate on a canary host pool, then roll the production pools onto the new version.
Rollback and validation
- Because versions are immutable in the gallery, rollback is just re-pointing a host pool at the prior version.
- Validate new images on a small canary pool before broad rollout.
- Tag versions with the patch month and a build ID so the lineage is obvious.
Treat the golden image as a product with its own versioned lifecycle. Automating it with Image Builder, a compute gallery and a pipeline removes drift, makes patching routine, and turns ‘who built this image and how?’ into a question with a real answer.
Need a hand with your AVD platform? 🚀
I help organisations design, migrate and optimise Azure Virtual Desktop. If you’re planning or troubleshooting a deployment, get in touch.