Azure Virtual Machines Resource Manager

Azure Resource Manager (ARM) is the deployment and management service for Azure. It provides a management layer that enables you to create, update, and delete resources in your Azure account. You use templates to deploy your resources consistently and repeatedly.

For Virtual Machines, ARM templates allow you to define the entire infrastructure needed for your VM, including the VM itself, its network interfaces, virtual networks, storage accounts, and more.

Key Concepts

Understanding the following concepts is crucial when working with Azure VMs and Resource Manager:

Deploying a Virtual Machine with ARM Templates

Here's a simplified example of an ARM template for deploying a basic Windows Virtual Machine:

ARM Template (JSON)
Parameters
Outputs
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vmName": {
            "type": "string",
            "metadata": {
                "description": "Name of the Virtual Machine."
            }
        },
        "adminUsername": {
            "type": "string",
            "metadata": {
                "description": "Admin username for the Virtual Machine."
            }
        },
        "adminPassword": {
            "type": "securestring",
            "metadata": {
                "description": "Admin password for the Virtual Machine."
            }
        },
        "vmSize": {
            "type": "string",
            "defaultValue": "Standard_DS1_v2",
            "metadata": {
                "description": "Size of the Virtual Machine."
            }
        },
        "osType": {
            "type": "string",
            "defaultValue": "Windows",
            "allowedValues": [
                "Windows",
                "Linux"
            ],
            "metadata": {
                "description": "Operating system type."
            }
        },
        "imageReference": {
            "type": "object",
            "defaultValue": {
                "publisher": "MicrosoftWindowsServer",
                "offer": "WindowsServer",
                "sku": "2019-Datacenter",
                "version": "latest"
            },
            "metadata": {
                "description": "Image reference for the Virtual Machine."
            }
        }
    },
    "variables": {
        "nicName": "[concat(parameters('vmName'), '-nic')]",
        "vnetName": "[concat(parameters('vmName'), '-vnet')]",
        "subnetName": "[concat(parameters('vmName'), '-subnet')]",
        "publicIpName": "[concat(parameters('vmName'), '-pip')]",
        "storageAccountName": "[toLower(concat(parameters('vmName'), uniqueString(resourceGroup().id)))]",
        "osDiskName": "[concat(parameters('vmName'), '-osdisk')]"
    },
    "resources": [
        {
            "type": "Microsoft.Network/virtualNetworks",
            "apiVersion": "2020-07-01",
            "name": "[variables('vnetName')]",
            "location": "[resourceGroup().location]",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "10.0.0.0/16"
                    ]
                },
                "subnets": [
                    {
                        "name": "[variables('subnetName')]",
                        "properties": {
                            "addressPrefix": "10.0.0.0/24"
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "apiVersion": "2020-07-01",
            "name": "[variables('publicIpName')]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "Standard",
                "tier": "Regional"
            },
            "properties": {
                "publicIPAllocationMethod": "Static",
                "dnsSettings": {
                    "domainNameLabel": "[toLower(concat(parameters('vmName'), '-dns'))]"
                }
            }
        },
        {
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2020-07-01",
            "name": "[variables('nicName')]",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
                "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpName'))]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), variables('subnetName'))]"
                            },
                            "publicIPAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpName'))]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2021-03-01",
            "name": "[parameters('vmName')]",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
            ],
            "properties": {
                "hardwareProfile": {
                    "vmSize": "[parameters('vmSize')]"
                },
                "storageProfile": {
                    "imageReference": "[parameters('imageReference')]",
                    "osDisk": {
                        "createOption": "FromImage",
                        "name": "[variables('osDiskName')]",
                        "managedDisk": {
                            "storageAccountType": "Premium_LRS"
                        }
                    }
                },
                "osProfile": {
                    "computerName": "[parameters('vmName')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]"
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
                        }
                    ]
                }
            }
        }
    ],
    "outputs": {
        "vmPublicIP": {
            "type": "string",
            "value": "[reference(variables('publicIpName')).ipAddress]"
        },
        "vmNameOutput": {
            "type": "string",
            "value": "[parameters('vmName')]"
        }
    }
}

You typically provide parameter values in a separate JSON file during deployment.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vmName": {
            "value": "myVMResource"
        },
        "adminUsername": {
            "value": "azureuser"
        },
        "adminPassword": {
            "value": "P@sswOrd123!"
        },
        "vmSize": {
            "value": "Standard_B2s"
        },
        "osType": {
            "value": "Windows"
        },
        "imageReference": {
            "value": {
                "publisher": "MicrosoftWindowsServer",
                "offer": "WindowsServer",
                "sku": "2019-Datacenter",
                "version": "latest"
            }
        }
    }
}

The outputs section in the template provides useful information after deployment, such as the public IP address.

Example outputs:

{
    "vmPublicIP": {
        "type": "string",
        "value": "20.118.69.100"
    },
    "vmNameOutput": {
        "type": "string",
        "value": "myVMResource"
    }
}