Azure Compute Templates
Azure Resource Manager (ARM) templates let you define the infrastructure and configuration for your Azure solutions in a declarative JSON file. This guide provides an overview of template structure, best practices, and examples specific to compute resources such as Virtual Machines, Scale Sets, and Containers.
Overview
Templates are composed of several top‑level sections:
- Schema – The JSON schema that defines the template format.
- Parameters – Input values that can be overridden at deployment time.
- Variables – Reusable expressions derived from parameters.
- Resources – The Azure resources to be provisioned.
- Outputs – Values returned after deployment.
Template Schema
The schema URL must be the first property of the template. The latest schema for Azure is:
{
"$schema": "https://schema.management.azure.com/schemas/2022-09-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
// ...
}
Sample Compute Template
The following example deploys a Windows Server virtual machine with a public IP address.
{
"$schema": "https://schema.management.azure.com/schemas/2022-09-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vmName": { "type": "string", "defaultValue": "myVM" },
"adminUsername": { "type": "string", "defaultValue": "azureuser" },
"adminPassword": { "type": "secureString" },
"vmSize": { "type": "string", "defaultValue": "Standard_DS1_v2" }
},
"variables": {
"nicName": "[concat(parameters('vmName'), '-nic')]",
"publicIPName": "[concat(parameters('vmName'), '-pip')]"
},
"resources": [
{
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2022-01-01",
"name": "[variables('publicIPName')]",
"location": "[resourceGroup().location]",
"properties": {
"publicIPAllocationMethod": "Dynamic"
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2022-01-01",
"name": "[variables('nicName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'myVnet', 'mySubnet')]"
},
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPName'))]"
}
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2022-03-01",
"name": "[parameters('vmName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"osProfile": {
"computerName": "[parameters('vmName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
},
"osDisk": {
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
}
]
}
}
}
],
"outputs": {
"adminUsername": {
"type": "string",
"value": "[parameters('adminUsername')]"
},
"publicIP": {
"type": "string",
"value": "[reference(variables('publicIPName')).ipAddress]"
}
}
}
Parameters
Define parameters to make your template reusable and environment‑agnostic.
| Name | Type | Default | Description |
|---|---|---|---|
| vmName | string | myVM | Name of the virtual machine. |
| adminUsername | string | azureuser | Admin user for the VM. |
| adminPassword | secureString | Secure admin password. | |
| vmSize | string | Standard_DS1_v2 | Size of the VM. |
Best Practices
- Store secret values in Azure Key Vault and reference them via
reference(). - Use
dependsOnonly when necessary; Azure resolves most dependencies automatically. - Leverage
linked templatesfor modular deployments. - Version your templates and use
contentVersionfor tracking changes.