๐ ARM Template โ Ubuntu VM Deployment
Azure Resource Manager (ARM) templates are the native JSON-based IaC format for Azure. All Bicep files compile down to ARM JSON. Understanding ARM templates gives you the deepest insight into how Azure resource deployments work under the hood.
ARMJSONAzure NativeUbuntu 22.04 LTSdependsOnARM Template โ azuredeploy.json
JSONCloudSchool.ai
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminUsername": {
"type": "string",
"defaultValue": "cloudadmin"
},
"adminPassword": {
"type": "securestring"
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"variables": {
"vmName": "cloudschool-ubuntu-vm",
"vnetName": "cloudschool-vnet",
"subnetName": "default",
"publicIpName": "cloudschool-pip",
"nicName": "cloudschool-nic",
"nsgName": "cloudschool-nsg",
"subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), variables('subnetName'))]"
},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2023-04-01",
"name": "[variables('nsgName')]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "Allow-SSH",
"properties": {
"priority": 1000,
"protocol": "Tcp",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "22"
}
}
]
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2023-04-01",
"name": "[variables('vnetName')]",
"location": "[parameters('location')]",
"dependsOn": ["[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"],
"properties": {
"addressSpace": { "addressPrefixes": ["10.0.0.0/16"] },
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
}
}
}
]
}
},
{
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2023-04-01",
"name": "[variables('publicIpName')]",
"location": "[parameters('location')]",
"sku": { "name": "Basic" },
"properties": { "publicIPAllocationMethod": "Dynamic" }
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2023-04-01",
"name": "[variables('nicName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"subnet": { "id": "[variables('subnetRef')]" },
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpName'))]"
},
"privateIPAllocationMethod": "Dynamic"
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2023-07-01",
"name": "[variables('vmName')]",
"location": "[parameters('location')]",
"dependsOn": ["[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"],
"properties": {
"hardwareProfile": { "vmSize": "Standard_B1s" },
"osProfile": {
"computerName": "[variables('vmName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "Canonical",
"offer": "0001-com-ubuntu-server-jammy",
"sku": "22_04-lts-gen2",
"version": "latest"
},
"osDisk": {
"createOption": "FromImage",
"managedDisk": { "storageAccountType": "Standard_LRS" }
}
},
"networkProfile": {
"networkInterfaces": [
{ "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" }
]
}
}
}
],
"outputs": {
"sshCommand": {
"type": "string",
"value": "[concat('ssh ', parameters('adminUsername'), '@<PUBLIC_IP_AFTER_DEPLOY>')]"
}
}
}Deployment Commands
BASHCloudSchool.ai
# Login to Azure
az login
# Create Resource Group
az group create --name rg-cloudschool-iac --location eastus
# Deploy ARM template
az deployment group create \
--resource-group rg-cloudschool-iac \
--template-file azuredeploy.json \
--parameters adminPassword='YourSecureP@ssw0rd!'
# Get the public IP
az vm show -d -g rg-cloudschool-iac -n cloudschool-ubuntu-vm --query publicIps -o tsv
# SSH into the VM
ssh cloudadmin@<PUBLIC_IP>Key Concepts
- dependsOn โ explicit dependency declarations (Bicep/Terraform infer these automatically)
- securestring โ parameter type that prevents the value from being logged
- variables() and resourceId() โ ARM template functions for dynamic references
- contentVersion โ used for template versioning and change tracking
๐ Continue learning: CloudSchool.ai Knowledge Base ยทIaC Glossary