Tutorial: Configure virtual machine scale sets in Azure using Ansible

Important

Ansible 2.7 (or later) is required to run the sample playbooks in this article.

Azure virtual machine scale sets is an Azure feature that lets you configure a group of identical, load balanced VMs. There's no additional cost to scale sets and they're built from virtual machines. You pay only for the underlying compute resources such as the VM instances, load balancers, or Managed Disk storage. With scale sets, the management and automation layers are provided to run and scale your applications. You could instead manually create and manage individual VMs. However, there are two key benefits to using scale sets. They're built into Azure and they automatically scale your virtual machines to meet application needs.

In this tutorial, Ansible is used to:

  • Configure the resources for a VM
  • Configure a scale set
  • Scale the scale set by increasing it's VM instances

Prerequisites

  • Azure subscription: If you don't have an Azure subscription, create a free account before you begin.

Configure a scale set

The playbook code in this section defines the following resources:

  • Resource group into which all of your resources will be deployed.
  • Virtual network in the 10.0.0.0/16 address space
  • Subnet within the virtual network
  • Public IP address that allows you to access resources across the Internet
  • Network security group that controls the flow of network traffic in and out of your scale set
  • Load balancer that distributes traffic across a set of defined VMs using load balancer rules
  • Virtual machine scale set that uses all the created resources

There are two ways to get the sample playbook:

  • Download the playbook and save it to vmss-create.yml.
  • Create a new file named vmss-create.yml and copy into it the following contents:
- hosts: localhost
  vars:
    resource_group: myResourceGroup
    vmss_name: myScaleSet
    vmss_lb_name: myScaleSetLb
    location: eastus
    admin_username: azureuser
    admin_password: "{{ admin_password }}"
  tasks:
    - name: Create a resource group
      azure_rm_resourcegroup:
        name: "{{ resource_group }}"
        location: "{{ location }}"
    - name: Create virtual network
      azure_rm_virtualnetwork:
        resource_group: "{{ resource_group }}"
        name: "{{ vmss_name }}"
        address_prefixes: "10.0.0.0/16"
    - name: Add subnet
      azure_rm_subnet:
        resource_group: "{{ resource_group }}"
        name: "{{ vmss_name }}"
        address_prefix: "10.0.1.0/24"
        virtual_network: "{{ vmss_name }}"
    - name: Create public IP address
      azure_rm_publicipaddress:
        resource_group: "{{ resource_group }}"
        allocation_method: Static
        name: "{{ vmss_name }}"
    - name: Create Network Security Group that allows SSH
      azure_rm_securitygroup:
        resource_group: "{{ resource_group }}"
        name: "{{ vmss_name }}"
        rules:
          - name: SSH
            protocol: Tcp
            destination_port_range: 22
            access: Allow
            priority: 1001
            direction: Inbound

    - name: Create a load balancer
      azure_rm_loadbalancer:
        name: "{{ vmss_lb_name }}"
        location: "{{ location }}"
        resource_group: "{{ resource_group }}"
        public_ip: "{{ vmss_name }}"
        probe_protocol: Tcp
        probe_port: 8080
        probe_interval: 10
        probe_fail_count: 3
        protocol: Tcp
        load_distribution: Default
        frontend_port: 80
        backend_port: 8080
        idle_timeout: 4
        natpool_frontend_port_start: 50000
        natpool_frontend_port_end: 50040
        natpool_backend_port: 22
        natpool_protocol: Tcp

    - name: Create Scale Set
      azure_rm_virtualmachinescaleset:
        resource_group: "{{ resource_group }}"
        name: "{{ vmss_name }}"
        vm_size: Standard_DS1_v2
        admin_username: "{{ admin_username }}"
        admin_password: "{{ admin_password }}"
        ssh_password_enabled: true
        capacity: 2
        virtual_network_name: "{{ vmss_name }}"
        subnet_name: "{{ vmss_name }}"
        upgrade_policy: Manual
        tier: Standard
        managed_disk_type: Standard_LRS
        os_disk_caching: ReadWrite
        image:
          offer: UbuntuServer
          publisher: Canonical
          sku: 16.04-LTS
          version: latest
        load_balancer: "{{ vmss_lb_name }}"
        data_disks:
          - lun: 0
            disk_size_gb: 20
            managed_disk_type: Standard_LRS
            caching: ReadOnly
          - lun: 1
            disk_size_gb: 30
            managed_disk_type: Standard_LRS
            caching: ReadOnly

Before running the playbook, see the following notes:

  • In the vars section, replace the {{ admin_password }} placeholder with your own password.

Run the playbook using the ansible-playbook command:

ansible-playbook vmss-create.yml

After running the playbook, you see output similar to the following results:

PLAY [localhost] 

TASK [Gathering Facts] 
ok: [localhost]

TASK [Create a resource group] 
changed: [localhost]

TASK [Create virtual network] 
changed: [localhost]

TASK [Add subnet] 
changed: [localhost]

TASK [Create public IP address] 
changed: [localhost]

TASK [Create Network Security Group that allows SSH] 
changed: [localhost]

TASK [Create a load balancer] 
changed: [localhost]

TASK [Create Scale Set] 
changed: [localhost]

PLAY RECAP 
localhost                  : ok=8    changed=7    unreachable=0    failed=0

View the number of VM instances

The configured scale set currently has two instances. The following steps are used to confirm that value:

  1. Sign in to the Azure portal.

  2. Navigate to the scale set you configured.

  3. You see the scale set name with the number of instances in parenthesis: Standard_DS1_v2 (2 instances)

  4. You can also verify the number of instances with the Azure Cloud Shell by running the following command:

    az vmss show -n myScaleSet -g myResourceGroup --query '{"capacity":sku.capacity}' 
    

    The results of running the Azure CLI command in Cloud Shell show that three instances now exist:

    {
      "capacity": 3,
    }
    

Scale out a scale set

The playbook code in this section retrieves information about the scale set and changes its capacity from two to three.

There are two ways to get the sample playbook:

  • Download the playbook and save it to vmss-scale-out.yml.
  • Create a new file named vmss-scale-out.yml and copy into it the following contents:
- hosts: localhost
  vars:
    resource_group: myResourceGroup
    vmss_name: myScaleSet
  tasks: 
    - name: Get scaleset info
      azure_rm_virtualmachine_scaleset_facts:
        resource_group: "{{ resource_group }}"
        name: "{{ vmss_name }}"
        format: curated
      register: output_scaleset

    - name: Dump scaleset info
      debug:
        var: output_scaleset

    - name: Modify scaleset (change the capacity to 3)
      set_fact:
        body: "{{ output_scaleset.ansible_facts.azure_vmss[0] | combine({'capacity': 3}, recursive=True) }}"

    - name: Update something in that scale set
      azure_rm_virtualmachinescaleset: "{{ body }}"

Run the playbook using the ansible-playbook command:

ansible-playbook vmss-scale-out.yml

After running the playbook, you see output similar to the following results:

PLAY [localhost] 

TASK [Gathering Facts] 
ok: [localhost]

TASK [Get scaleset info] 
ok: [localhost]

TASK [Dump scaleset info] 
ok: [localhost] => {
    "output_scaleset": {
        "ansible_facts": {
            "azure_vmss": [
                {
                    ......
                }
            ]
        },
        "changed": false,
        "failed": false
    }
}

TASK [Modify scaleset (set upgradePolicy to Automatic and capacity to 3)] 
ok: [localhost]

TASK [Update something in that scale set] 
changed: [localhost]

PLAY RECAP 
localhost                  : ok=5    changed=1    unreachable=0    failed=0

Verify the results

Verify your results of your work via the Azure portal:

  1. Sign in to the Azure portal.

  2. Navigate to the scale set you configured.

  3. You see the scale set name with the number of instances in parenthesis: Standard_DS1_v2 (3 instances)

  4. You can also verify the change with the Azure Cloud Shell by running the following command:

    az vmss show -n myScaleSet -g myResourceGroup --query '{"capacity":sku.capacity}' 
    

    The results of running the Azure CLI command in Cloud Shell show that three instances now exist:

    {
      "capacity": 3,
    }
    

Next steps