This guide walks you through creating a Windows Virtual Machine (VM) in Azure using an Azure Resource Manager (ARM) template. ARM templates allow you to define your infrastructure as code, enabling consistent and repeatable deployments.
An ARM template is a JavaScript Object Notation (JSON) file that defines the infrastructure for your solution. It typically includes:
resources: The core of the template, defining the Azure resources to deploy (e.g., VM, virtual network, storage account).parameters: Input values that can be customized during deployment.variables: Values that can be reused within the template.outputs: Values returned after deployment.Below is a simplified ARM template to deploy a Windows Server 2019 Datacenter VM. You can save this as azuredeploy.json.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vmName": {
"type": "string",
"defaultValue": "myWindowsVM",
"metadata": {
"description": "Name of the Windows virtual machine."
}
},
"adminUsername": {
"type": "string",
"defaultValue": "azureuser",
"metadata": {
"description": "Administrator username for the virtual machine."
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Administrator password for the virtual machine."
}
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_DS1_v2",
"allowedValues": [
"Standard_DS1_v2",
"Standard_DS2_v2",
"Standard_B1s"
],
"metadata": {
"description": "Size of the virtual machine."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for the virtual machine."
}
}
},
"variables": {
"nicName": "[concat(parameters('vmName'), '-nic')]",
"vnetName": "[concat(parameters('vmName'), '-vnet')]",
"subnetName": "[concat(parameters('vmName'), '-subnet')]",
"publicIpName": "[concat(parameters('vmName'), '-publicip')]",
"osDiskName": "[concat(parameters('vmName'), '-osdisk')]",
"networkSecurityGroupName": "[concat(parameters('vmName'), '-nsg')]"
},
"resources": [
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-11-01",
"name": "[variables('vnetName')]",
"location": "[parameters('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-11-01",
"name": "[variables('publicIpName')]",
"location": "[parameters('location')]",
"properties": {
"dnsSettings": {
"domainNameLabel": "[concat(parameters('vmName'), '-dns')]"
},
"publicIPAllocationMethod": "Static"
}
},
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-11-01",
"name": "[variables('networkSecurityGroupName')]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "RDP",
"properties": {
"priority": 1000,
"access": "Allow",
"direction": "Inbound",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*"
}
}
]
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2020-11-01",
"name": "[variables('nicName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
"[resourceId('Microsoft.Network/publicIpAddresses', variables('publicIpName'))]",
"[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), variables('subnetName'))]"
},
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIpAddresses', variables('publicIpName'))]"
}
}
}
],
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
}
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2020-12-01",
"name": "[parameters('vmName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
},
"osDisk": {
"createOption": "FromImage",
"name": "[variables('osDiskName')]"
}
},
"osProfile": {
"computerName": "[parameters('vmName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
}
]
}
}
}
],
"outputs": {
"publicIpAddress": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Network/publicIpAddresses', variables('publicIpName'))).ipAddress]"
},
"vmName": {
"type": "string",
"value": "[parameters('vmName')]"
}
}
}
securestring, which means it should be handled securely during deployment.
You can deploy the ARM template using Azure CLI or Azure PowerShell.
Save the template above as azuredeploy.json. Then, run the following command in your terminal:
az deployment group create \
--name MyVMDeployment \
--resource-group YourResourceGroupName \
--template-file azuredeploy.json \
--parameters vmName=myTestVM adminUsername=testuser adminPassword='YourSecurePasswordHere!'
Replace YourResourceGroupName with the name of your Azure resource group and 'YourSecurePasswordHere!' with a strong password.
Save the template above as azuredeploy.json. Then, run the following command:
New-AzResourceGroupDeployment `
-Name "MyVMDeployment" `
-ResourceGroupName "YourResourceGroupName" `
-TemplateFile "azuredeploy.json" `
-vmName "myTestVM" `
-adminUsername "testuser" `
-adminPassword "YourSecurePasswordHere!"
Replace YourResourceGroupName with the name of your Azure resource group and "YourSecurePasswordHere!" with a strong password.
For more detailed information and advanced configurations, refer to the full Azure VM documentation.