Learn about Virtual Machine Scale Set templates
Azure Resource Manager templates are a great way to deploy groups of related resources. This tutorial series shows how to create a basic scale set template and how to modify this template to suit various scenarios. All examples come from this GitHub repository.
This template is intended to be simple. For more complete examples of scale set templates, see the Azure Quickstart Templates GitHub repository and search for folders that contain the string vmss
.
If you are already familiar with creating templates, you can skip to the "Next steps" section to see how to modify this template.
Define $schema and contentVersion
First, define $schema
and contentVersion
in the template. The $schema
element defines the version of the template language and is used for Visual Studio syntax highlighting and similar validation features. The contentVersion
element is not used by Azure. Instead, it helps you keep track of the template version.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
}
Define parameters
Next, define two parameters, adminUsername
and adminPassword
. Parameters are values you specify at the time of deployment. The adminUsername
parameter is simply a string
type, but because adminPassword
is a secret, give it type securestring
. Later, these parameters are passed into the scale set configuration.
"parameters": {
"adminUsername": {
"type": "string"
},
"adminPassword": {
"type": "securestring"
}
},
Define variables
Resource Manager templates also let you define variables to be used later in the template. The example doesn't use any variables, so the JSON object is empty.
"variables": {},
Define resources
Next is the resources section of the template. Here, you define what you actually want to deploy. Unlike parameters
and variables
(which are JSON objects), resources
is a JSON list of JSON objects.
"resources": [
...
]
All resources require type
, name
, apiVersion
, and location
properties. This example's first resource has type Microsoft.Network/virtualNetwork, name myVnet
, and apiVersion 2018-11-01
. (To find the latest API version for a resource type, see the Azure Resource Manager template reference.)
{
"type": "Microsoft.Network/virtualNetworks",
"name": "myVnet",
"apiVersion": "2018-11-01",
}
Specify location
To specify the location for the virtual network, use a Resource Manager template function. This function must be enclosed in quotes and square brackets like this: "[<template-function>]"
. In this case, use the resourceGroup
function. It takes in no arguments and returns a JSON object with metadata about the resource group this deployment is being deployed to. The resource group is set by the user at the time of deployment. This value is then indexed into this JSON object with .location
to get the location from the JSON object.
"location": "[resourceGroup().location]",
Specify virtual network properties
Each Resource Manager resource has its own properties
section for configurations specific to the resource. In this case, specify that the virtual network should have one subnet using the private IP address range 10.0.0.0/16
. A scale set is always contained within one subnet. It cannot span subnets.
{
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "mySubnet",
"properties": {
"addressPrefix": "10.0.0.0/16"
}
}
]
}
},
Add dependsOn list
In addition to the required type
, name
, apiVersion
, and location
properties, each resource can have an optional dependsOn
list of strings. This list specifies which other resources from this deployment must finish before deploying this resource.
In this case, there is only one element in the list, the virtual network from the previous example. You specify this dependency because the scale set needs the network to exist before creating any VMs. This way, the scale set can give these VMs private IP addresses from the IP address range previously specified in the network properties. The format of each string in the dependsOn list is <type>/<name>
. Use the same type
and name
used previously in the virtual network resource definition.
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"name": "myScaleSet",
"apiVersion": "2019-03-01",
"location": "[resourceGroup().location]",
"dependsOn": [
"Microsoft.Network/virtualNetworks/myVnet"
],
...
}
Specify scale set properties
Scale sets have many properties for customizing the VMs in the scale set. For a full list of these properties, see the template reference. For this tutorial, only a few commonly used properties are set.
Supply VM size and capacity
The scale set needs to know what size of VM to create ("sku name") and how many such VMs to create ("sku capacity"). To see which VM sizes are available, see the VM Sizes documentation.
"sku": {
"name": "Standard_A1",
"capacity": 2
},
Choose type of updates
The scale set also needs to know how to handle updates on the scale set. Currently, there are three options, Manual
, Rolling
and Automatic
. For more information on the differences between the two, see the documentation on how to upgrade a scale set.
"properties": {
"upgradePolicy": {
"mode": "Manual"
},
}
Choose VM operating system
The scale set needs to know what operating system to put on the VMs. Here, create the VMs with a fully patched Ubuntu 16.04-LTS image.
"virtualMachineProfile": {
"storageProfile": {
"imageReference": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "16.04-LTS",
"version": "latest"
}
},
}
Specify computerNamePrefix
The scale set deploys multiple VMs. Instead of specifying each VM name, specify computerNamePrefix
. The scale set appends an index to the prefix for each VM, so VM names have the form <computerNamePrefix>_<auto-generated-index>
.
In the following snippet, use the parameters from before to set the administrator username and password for all VMs in the scale set. This process uses the parameters
template function. This function takes in a string that specifies which parameter to refer to and outputs the value for that parameter.
"osProfile": {
"computerNamePrefix": "vm",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
Specify VM network configuration
Finally, specify the network configuration for the VMs in the scale set. In this case, you only need to specify the ID of the subnet created earlier. This tells the scale set to put the network interfaces in this subnet.
You can get the ID of the virtual network containing the subnet by using the resourceId
template function. This function takes in the type and name of a resource and returns the fully qualified identifier of that resource. This ID has the form: /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/<resourceProviderNamespace>/<resourceType>/<resourceName>
However, the identifier of the virtual network is not enough. Provide the specific subnet that the scale set VMs should be in. To do this, concatenate /subnets/mySubnet
to the ID of the virtual network. The result is the fully qualified ID of the subnet. Do this concatenation with the concat
function, which takes in a series of strings and returns their concatenation.
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "myNic",
"properties": {
"primary": "true",
"ipConfigurations": [
{
"name": "myIpConfig",
"properties": {
"subnet": {
"id": "[concat(resourceId('Microsoft.Network/virtualNetworks', 'myVnet'), '/subnets/mySubnet')]"
}
}
}
]
}
}
]
}
Next steps
You can deploy the preceding template by following the Azure Resource Manager documentation.
You can start this tutorial series from the basic scale set template article.
You can see how to modify the basic scale set template to deploy the scale set into an existing virtual network.
You can see how to modify the basic scale set template to deploy the scale set with a custom image.
You can see how to modify the basic scale set template to deploy a Linux scale set with guest-based autoscale.
For more information about scale sets, refer to the scale set overview page.