DevOps Peach

Azure Basics · Azure Resources – Tools, Resource Manager and ARM Templates · Lesson 4 of 4

ARM Templates, Bicep and QuickStarts

An ARM template describes infrastructure in JSON (parameters, variables, resources, outputs); deploy it with `az deployment group create` and preview it with `what-if`; Bicep is a shorter syntax that compiles to ARM.

Practice interactively →

Infrastructure as code gives consistent, repeatable deployments for Dev/QA/Prod, fewer manual steps, code review, reuse and modules.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageName": { "type": "string", "minLength": 3, "maxLength": 24 },
    "adminPassword": { "type": "securestring" }
  },
  "variables": { "skuName": "Standard_LRS" },
  "resources": [{
    "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2023-05-01",
    "name": "[parameters('storageName')]", "location": "[resourceGroup().location]",
    "sku": { "name": "[variables('skuName')]" }, "kind": "StorageV2"
  }],
  "outputs": { "storageId": { "type": "string", "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]" } }
}
Block Role
parameters Values passed in at deploy time (--parameters k=v or @file.json)
variables Values computed inside the template
resources Resources to create
outputs Values returned after the deployment

Secrets use securestring (hidden from logs and deployment history), not string.

flowchart LR
  B["main.bicep"] -- "az bicep build" --> J["main.json (ARM)"]
  Q["QuickStart template<br/>(GitHub)"] --> J
  J --> W["az deployment group what-if"]
  J --> D["az deployment group create"]
  D --> RG["rg-devops-lab"]
Command Meaning
az deployment group what-if -g rg-devops-lab -f azuredeploy.json -p storageName=stdevopslab01 Preview the changes
az deployment group create -g rg-devops-lab -f azuredeploy.json -p storageName=stdevopslab01 Deploy
az group delete -n rg-devops-lab --yes --no-wait Clean up the lab

The same storage account in Bicep

param storageName string
param location string = resourceGroup().location

resource st 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageName
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
}

output storageId string = st.id

Bicep compiles to the same ARM JSON, but it infers dependencies from references (here st.id), supports modules, and is much shorter. Microsoft recommends Bicep for new work.

Useful template features

Feature Purpose
uniqueString(resourceGroup().id) Deterministic suffix for globally unique names
dependsOn Explicit order in JSON when no reference links two resources
Parameter file (azuredeploy.parameters.json or .bicepparam) Keep per-environment values out of the template
copy loop Create several similar resources
condition Deploy a resource only when an expression is true

Deployment scopes

Templates can target more than a resource group: az deployment sub create deploys at subscription scope (for example to create resource groups or policy assignments), and az deployment mg create and az deployment tenant create go higher still. A subscription deployment needs --location to store its metadata.

Reuse and lifecycle

Each deployment is recorded in the resource group's deployment history, which keeps the most recent 800 entries.

Practice interactively →