Azure

Migrating your applications to Azure using Virtual Machine Scale Sets, Packer and Virtual Machine extensions – Part 2

3 min read

This is a continuation of the previous post about migrating your not ready cloud application to the Azure cloud. The last post discussed about creating a managed image to be able to be used by a virtual machine scale set for provisioning.

What will we do in this series

I decided to do a series of posts about this topic as it touches a variety of aspects. I will use a concrete example that may or may not have happened to you and I plan to cover

Creating the necessary resources

Creating the Virtual Machine Scale Set requires the following Azure resources:

  • Virtual Network (vNet)
    • includes a subnet
  • Network Security Group (NSG) to able to access the VMs in the Virtual Machine Scalet Set
  • Virtual Machine Scalet Set (VMSS)
    • includes the HealthExtension to be able to do rolling updates for new images we create
  • Load Balancer (LB)
    • includes the Public IP address for the LB

We will construct our provisioning using an Azure Resource Manager (ARM) template. We will also populate the parameters and variables section with the necessary information the template needs.

Note that I cannot cover all bases when it comes to options and scenarios. You will need to adapt this to your environment.

Also note that this is for educational purposes. In a production environment, you will need to restrict and tweak some or all resources.

Tip: if you want to use comments in your arm templates, rename your file(s) to the jsonc extension.

Virtual Network

The first resource we need is a vnet. To create a vnet and the associated subnet we need to add the following to the ARM template resources array:

Network Security Group

Next is a Network Security Group. A NSG is necessary to allow traffic when you use a public load balancer. If you don’t add a NSG to your subnet, no traffic will be able to flow through.

Here, I am allowing HTTP traffic along with SSH traffic. Since we’re load balanced, we need to be able to access the underlying VMs machine. Our load balancer will have NAT rules to transfer traffic to the underlying VMs SSH port (22), and each VM will be associated a port from the content of the variable nsgSSHNATPortRange. This port range has to closely be related to the maximum number of VMs our scale set can handle (capacity).

Virtual Machine Scale Set

The following ARM definition defines the scale set.

We assigned a Managed Identity of type system, using the identity property to this VMSS. In the next post, we will grant this identity access to a storage account where we will be able to fetch files in our extensions.

Load Balancer

It’s important to note in the inboundNatPools (only) object, the properties frontendRangeStart and frontendRangeEnd. The rangeStart and rangeEnd have to match the number of instances that the VMSS can have. In this case, 0-19 (inclusives) means that we will be able to communicate with at most 20 VMs in our Scale Set. One port will be assigned to one VM in the set. As stated above, the capacity property of the VMSS cannot exceed 20 in this case.

Public IP

Parameters, variables and output variables

We are outputting the vmssName as we will need it to provision the extension as it will be described the next post in this series.

Final words

Adding all of those into a json/jsonc file and you will have the necessary ARM template to deploy the VMSS and its necessary components.

You can find the full template in my GitHub repository.