ARM Templates
Template Structure
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": { ... },
"variables": { ... },
"functions": [ ... ],
"resources": [ ... ],
"outputs": { ... }
}
Parameters
"parameters": {
"storageAccountName": {
"type": "string",
"minLength": 3,
"maxLength": 24,
"metadata": {
"description": "Storage account name (3-24 chars, lowercase)"
}
},
"environment": {
"type": "string",
"defaultValue": "dev",
"allowedValues": ["dev", "staging", "prod"]
},
"adminPassword": {
"type": "securestring"
},
"tagValues": {
"type": "object",
"defaultValue": {
"environment": "dev",
"team": "platform"
}
}
}
Variables & Functions
"variables": {
"storageAccountName": "[toLower(concat('storage', uniqueString(resourceGroup().id)))]",
"location": "[resourceGroup().location]",
"subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), 'default')]",
"isProd": "[equals(parameters('environment'), 'prod')]",
"vmSize": "[if(variables('isProd'), 'Standard_D4s_v3', 'Standard_B2s')]"
}
// Common ARM functions:
// concat(s1, s2) - string concatenation
// uniqueString(str) - deterministic hash (13 chars)
// resourceId(type, name) - get resource ID
// reference(id) - get resource properties
// parameters('name') - access parameter value
// variables('name') - access variable value
// resourceGroup() - current resource group info
// subscription() - current subscription info
Resource Examples
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[variables('storageAccountName')]",
"location": "[variables('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"tags": "[parameters('tagValues')]",
"properties": {
"supportsHttpsTrafficOnly": true,
"minimumTlsVersion": "TLS1_2"
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2022-09-01",
"name": "[parameters('appPlanName')]",
"location": "[variables('location')]",
"sku": {
"name": "B2",
"tier": "Basic"
},
"properties": {
"reserved": true
}
}
]
Outputs
"outputs": {
"storageAccountId": {
"type": "string",
"value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
},
"storageEndpoint": {
"type": "string",
"value": "[reference(variables('storageAccountName')).primaryEndpoints.blob]"
},
"connectionString": {
"type": "securestring",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountName'), '2023-01-01').keys[0].value)]"
}
}
# Deploy template
az deployment group create \
--resource-group myRG \
--template-file template.json \
--parameters @params.dev.json
# What-if (preview changes)
az deployment group what-if \
--resource-group myRG \
--template-file template.json
Linked Templates
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "storageDeployment",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "https://mystorageacct.blob.core.windows.net/templates/storage.json",
"contentVersion": "1.0.0.0"
},
"parametersLink": {
"uri": "https://mystorageacct.blob.core.windows.net/templates/storage.params.json"
}
}
}
// Bicep (modern alternative to ARM JSON)
// storage.bicep
param storageAccountName string
param location string = resourceGroup().location
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageAccountName
location: location
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
}
output id string = storageAccount.id