Domain 3 β€” Module 1 of 7 14%
12 of 27 overall
Domain 3: Deploy and Manage Azure Compute Resources Free ⏱ ~14 min read

ARM Templates & Bicep: Infrastructure as Code

Azure Resource Manager templates and Bicep files let you define infrastructure in code β€” deploy the same environment every time, no clicking required. Learn to read, modify, and deploy them like an Azure admin pro.

What is Infrastructure as Code?

Simple explanation

Infrastructure as Code is like a recipe for your Azure environment.

Instead of clicking through the Azure portal to create a VM, a storage account, and a network, you write it all down in a file. Then you run the file and Azure creates everything automatically. Need the same setup in another region? Run the same file. Need to recreate after a disaster? Run the same file.

Azure supports two languages for this: ARM templates (JSON β€” verbose but powerful) and Bicep (cleaner syntax, compiles to ARM). Both do the same job; Bicep is just easier to read and write.

ARM template structure

Every ARM template has this structure:

// ARM Template (JSON)
// "$schema": defines the template version
// "contentVersion": your versioning
// "parameters": inputs (like VM name, size)
// "variables": computed values
// "resources": what to create
// "outputs": values returned after deployment

The sections you must know:

SectionPurposeRequired?
$schemaTemplate format versionYes
contentVersionYour template version (e.g., β€œ1.0.0.0”)Yes
parametersUser inputs at deploy time (VM name, size, location)No
variablesComputed values used in the templateNo
resourcesThe Azure resources to createYes
outputsValues returned after deployment (like IP addresses)No

Bicep β€” the cleaner alternative

Bicep does the same thing as ARM JSON but with much cleaner syntax:

ARM Template FeatureARM JSONBicep
Parameter”parameters” section with type definitionsparam vmName string
Variable”variables” sectionvar subnetId = ...
ResourceNested JSON object in β€œresources” arrayresource vm 'Microsoft.Compute/virtualMachines@2023-03-01'
Reference another resource[resourceId(...)] functionstorageAccount.id (direct reference)
String concatenation[concat('vm-', parameters('name'))]String interpolation: 'vm-$dollarleftbracename}'
ARM JSON vs Bicep β€” Bicep compiles to ARM, so they produce identical deployments
FeatureARM Template (JSON)Bicep
LanguageJSON β€” verbose, curly braces everywhereDomain-specific β€” clean, concise syntax
Learning curveSteep β€” deeply nested JSONGentle β€” reads almost like pseudocode
ToolingVS Code extension, Azure portalVS Code extension with intellisense, linting, formatting
Module supportLinked/nested templates (complex)Native modules (simple imports)
Deployment engineAzure Resource ManagerCompiles to ARM JSON β€” same engine
Which to learn?Read existing templatesWrite new infrastructure
Exam tip: You need to READ templates, not write from scratch

The exam tests whether you can interpret and modify templates β€” not write them from memory. You’ll see a template snippet and be asked: β€œWhat does this deploy?” or β€œWhat parameter needs to change to use a different VM size?”

Focus on understanding the structure: find the resource type, find the parameters, understand what values are being used.

Deploying templates

Four ways to deploy ARM/Bicep templates:

MethodCommand
Azure CLIaz deployment group create --resource-group myRG --template-file main.bicep
PowerShellNew-AzResourceGroupDeployment -ResourceGroupName myRG -TemplateFile main.bicep
Azure PortalUpload template in β€œDeploy a custom template”
Cloud ShellSame CLI/PowerShell commands in the browser

Deployment modes:

  • Incremental (default) β€” adds resources defined in the template; leaves existing resources untouched
  • Complete β€” adds resources AND deletes any resources in the resource group that aren’t in the template
Exam tip: Complete mode is dangerous

Complete mode deletes resources not in the template. If you deploy a template with only a VM in Complete mode to a resource group that has a VM and a database, the database gets deleted. The exam tests whether you understand this distinction. Default is Incremental (safe). Always specify explicitly.

Exporting and converting

Export an existing deployment as ARM template:

  • Azure Portal β†’ Resource Group β†’ Deployments β†’ select deployment β†’ Download template
  • Azure Portal β†’ Resource β†’ Export template (sidebar)
  • CLI: az group export --name myResourceGroup

Convert ARM JSON to Bicep:

az bicep decompile --file template.json

Convert Bicep to ARM JSON:

az bicep build --file main.bicep
Question

What are the two deployment modes for ARM templates?

Click or press Enter to reveal answer

Answer

Incremental (default) β€” adds/updates resources in the template but leaves others untouched. Complete β€” adds/updates resources AND deletes any resources in the resource group that are NOT defined in the template. Complete mode is destructive.

Click to flip back

Question

What is the relationship between Bicep and ARM templates?

Click or press Enter to reveal answer

Answer

Bicep is a domain-specific language that compiles to ARM template JSON. It provides cleaner syntax but produces identical deployments. Bicep is not a separate deployment engine β€” it transpiles to the same ARM JSON that Azure Resource Manager processes.

Click to flip back

Question

How do you convert an existing ARM JSON template to Bicep?

Click or press Enter to reveal answer

Answer

Use the Azure CLI command: az bicep decompile --file template.json. This converts ARM JSON syntax to Bicep syntax. The reverse (Bicep to ARM) uses: az bicep build --file main.bicep.

Click to flip back

Knowledge check

Knowledge Check

Alex deploys an ARM template in Complete mode to a resource group that contains a VM, a storage account, and a SQL database. The template only defines the VM. What happens to the storage account and SQL database?

Knowledge Check

A Bicep file contains: param location string = 'uksouth'. What does this line define?