Table of contents

Azure virtual machine scale sets and Workload Security

Azure virtual machine scale sets (VMSS) provide the ability to deploy and manage a set of identical VMs. The number of VMs can increase or decrease automatically based on configurable scaling rules. For more information, see What are virtual machine scale sets in Azure?

You can set up your VMSS to include a base VM image that has the agent pre-installed and pre-activated. As the VMSS scales up, the new VM instances in the scale set automatically include the agent.

To add the agent to your VMSS:

Step 1: Add your Azure account to Workload Security (recommended)

When you add your Azure account to Workload Security, all the Azure instances created under that account are loaded into Workload Security and appear under Computers. The instances appear regardless of whether they have an agent installed or not. The ones that do not include an agent have a Status of No Agent. After you install and activate the agent on them, their Status changes to Managed (Online).

If the scale set is manually or automatically scaled up after adding your Azure account, Workload Security detects the new Azure instances and adds them to its list under Computers. Similarly, if the scale set is scaled down, the instances are removed from view. Thus, Workload Security always shows the current list of available Azure instances in your scale set.

However, if you do not add your Azure account to Workload Security, but instead add individual Azure instances using another method, then Workload Security does not detect any scaling down that might occur, and does not remove the non-existent Azure instances from its list. To prevent an ever-expanding list of Azure VMs in Workload Security, and to always show exactly which Azure instances are available in your scale set at any one time, it is highly recommended that you add your Azure account to Workload Security.

For instructions on adding your Azure account, see Add a Microsoft Azure account to Workload Security.

Step 2: Prepare a deployment script

In Workload Security, prepare a deployment script. For instructions, see Use deployment scripts to add and protect computers. This deployment script will be referenced in a custom script extension that you'll configure next.

To run a custom script with the following VMSS script, the script must be stored in Azure Blob storage or in any other location accessible through a valid URL. For instructions on how to upload a file to Azure Blob storage, see Perform Azure Blob storage operations with Azure PowerShell.

Step 3: Add the agent through a custom script extension to your VMSS instances

The following are examples on how to use PowerShell to add the agent:

  • Example 1 shows how to create a new VMSS that includes the agent.
  • Example 2 shows how to add the agent to an existing VMSS.

Both examples:

For instructions on creating a new VMSS using PowerShell cmdlets, refer to this Microsoft tutorial. For the Linux platform, see https://github.com/Azure/custom-script-extension-linux.

Example 1: Create a new VMSS that includes the agent

$resourceGroupName = <The resource group of the VMSS>
$vmssname = <The name of the VMSS>

# Create ResourceGroup
New-AzureRmResourceGroup -ResourceGroupName $resourceGroupName -Location EastUS

# Create a config object
$vmssConfig = New-AzureRmVmssConfig `
 -Location EastUS `
 -SkuCapacity 2 `
 -SkuName Standard_DS2 `
 -UpgradePolicyMode Automatic

# Define the script for your Custom Script Extension to run on the Windows Platform
$customConfig = @{
 "fileUris" = (,"A URL of your copy of deployment script, ex. deploymentscript.ps1");
 "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File deploymentscript.ps1"
}

# Define the script for your Custom Script Extension to run on the Linux Platform
#$customConfig = @{
# "fileUris" = (,"A URL of your copy of deployment script, ex. deploymentscript.sh");
# "commandToExecute" = "bash deploymentscript.sh"
#}

# The section is required only if deploymentscript has been located within Azure StorageAccount
$storageAccountName = <StorageAccountName if deploymentscript is locate in Azure Storage>
$key = (Get-AzureRmStorageAccountKey -Name $storageAccountName -ResourceGroupName $resourceGroupName).Value[0]
$protectedConfig = @{
 "storageAccountName" = $storageAccountName;
 "storageAccountKey" = $key
}

# Use Custom Script Extension to install the agent (Windows)
Add-AzureRmVmssExtension -VirtualMachineScaleSet $vmssConfig `
 -Name "customScript" `
 -Publisher "Microsoft.Compute" `
 -Type "CustomScriptExtension" `
 -TypeHandlerVersion 1.8 `
 -Setting $customConfig `
 -ProtectedSetting $protectedConfig

# Use Custom Script Extension to install the agent (Linux)
#Add-AzureRmVmssExtension -VirtualMachineScaleSet $vmssConfig `
# -Name "customScript" `
# -Publisher "Microsoft.Azure.Extensions" `
# -Type "customScript" `
# -TypeHandlerVersion 2.0 `
# -Setting $customConfig `
# -ProtectedSetting $protectedConfig

# Create a public IP address
# Create a frontend and backend IP pool
# Create the load balancer
# Create a load balancer health probe on port 80
# Create a load balancer rule to distribute traffic on port 80
# Update the load balancer configuration
# Reference a virtual machine image from the gallery
# Set up information for authenticating with the virtual machine
# Create the virtual network resources
# Attach the virtual network to the config object

# Create the scale set with the config object (this step might take a few minutes)
New-AzureRmVmss `
 -ResourceGroupName $resourceGroupName `
 -Name $vmssname `
 -VirtualMachineScaleSet $vmssConfig

Example 2: Add the agent to an existing VMSS

$resourceGroupName = <The resource group of the VMSS>
$vmssname = <The name of the VMSS>

# Get the VMSS model
$vmssobj = Get-AzureRmVmss -ResourceGroupName $resourceGroupName -VMScaleSetName $vmssname

# Show model data if you prefer
# Write-Output $vmssobj

# Define the script for your Custom Script Extension to run on the Windows platform
$customConfig = @{
 "fileUris" = (,"A URL of your copy of deployment script, ex. deploymentscript.ps1");
 "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File deploymentscript.ps1"
}

# Define the script for your Custom Script Extension to run on the Linux platform
#$customConfig = @{
# "fileUris" = (,"A URL of your copy of deployment script, ex. deploymentscript.sh");
# "commandToExecute" = "bash deploymentscript.sh"
#}

# The section is required only if deploymentscript has been located within Azure StorageAccount
$storageAccountName = <StorageAccountName if deploymentscript is locate in Azure Storage>
$key= (Get-AzureRmStorageAccountKey -Name $storageAccountName -ResourceGroupName $resourceGroupName).Value[0]
$protectedConfig = @{
 "storageAccountName" = $storageAccountName;
 "storageAccountKey" = $key
}

# Use Custom Script Extension to install the agent (Windows)
$newvmssobj = Add-AzureRmVmssExtension `
 -VirtualMachineScaleSet $vmssobj `
 -Name "customScript" `
 -Publisher "Microsoft.Compute" `
 -Type "CustomScriptExtension" `
 -TypeHandlerVersion 1.8 `
 -Setting $customConfig `
 -ProtectedSetting $protectedConfig

# Use Custom Script Extension to install the agent (Linux)
#$newvmssobj = Add-AzureRmVmssExtension `
# -VirtualMachineScaleSet $vmssobj `
# -Name "customScript" `
# -Publisher "Microsoft.Azure.Extensions" `
# -Type "customScript" `
# -TypeHandlerVersion 2.0 `
# -Setting $customConfig `
# -ProtectedSetting $protectedConfig

# Update the virtual machine scale set model
Update-AzureRmVmss -ResourceGroupName $resourceGroupName -name $vmssname -VirtualMachineScaleSet $newvmssobj -Verbose

# Get Instance ID for all instances in this VMSS, and decide which instance you'd like to update
# Get-AzureRmVmssVM -ResourceGroupName $resourceGroupName -VMScaleSetName $vmssname

# Now start updating instances
# If upgradePolicy is Automatic in the VMSS, do NOT execute the next command Update-AzureRmVmssInstance. Azure will auto-update the VMSS.
# There's no PowerShell command to update all instances at once. But you could refer to the output of Update-AzureRmVmss, and loop all instances into this command.
Update-AzureRmVmssInstance -ResourceGroupName $resourceGroupName -VMScaleSetName $vmssname -InstanceId 0