Load Balancing Fleets of Storage with Ansible

In this post, I’m going to discuss how to load balance your storage provisioning across a fleet of Pure Storage FlashArrays using Ansible.

What would a use case be for this?

Imagine a vSphere environment where there are multiple Pure Storage FlashArrays available to a vCenter and when creating a new datastore, you want to do this on the least full array.

What I wanted to do was orchestrate which storage array a volume was provisioned on automatically without the storage administrator having to keep checking which array to use. Now, when I think of automation and orchestration I immediately think of Ansible.

Pure Storage has an amazing suite of modules for Ansible that we can leverage to do this work, so I created an Ansible load-balancing role called, logically enough, lb.

The role takes a list of arrays, interrogates them and works out which has the least used capacity and then provides the information required for the rest of the playbook to provision against that array.

Whilst this example only uses spare capacity as the driver for array selection, you could easily make this much more intelligent and use other parameters such as array performance, the number of volumes on the array or even array health in an algorithm to select the best array to use next.

So where can you find this role and how do you use it?

The role can be found on the Pure Storage OpenConnect GitHub account in the ansible-playbook-examples repository, under the flasharray/roles directory.

To use it requires you to populate the variables file roles/lb/vars/main.yml with the management IP addresses of your fleet of arrays, together with an API token for a storage admin privilege user for each array. There is no limit to the number of arrays you can load balance over, but the example below is for a fleet of six FlashArrays.

The populated file would look something like this (use your own array credentials):

---
arrays:
  - url: 10.21.200.xxx
    api: c6033033-fe69-2515-a9e8-966bb7fe4b40
  - url: 10.21.230.xxx
    api: 70e2e819-df9d-54d7-7af3-6aa9bd72b20b
  - url: 10.21.229.xxx
    api: f5dda863-5275-d092-f747-8eeac4d54006
  - url: 10.21.228.xxx
    api: 96abbb22-f23f-af72-14cb-982c41291e79
  - url: 10.21.228.xxx
    api: 4ea6b496-7408-12bb-6dac-2be96100c070
  - url: 10.21.229.xxx
    api: 473c4f2d-1bc1-0bac-4417-891d988a46c0

To use the role add it to your Ansible playbook.

If you are security-minded, then all of these entries in the URL and API token can be encrypted using Ansible Vault. I wrote another blog post some time ago that included details on how to implement Vault for these variables.

When the role has run two variables will have been defined: use_url and use_api. These identify the array with the lowest utilization level and therefore the one you should be provisioning to. There is also an additional variable you can use (use_name) that identifies the true name of the array selected.

A super simple playbook that uses the lb role and then provisions a single volume to the least full array is shown here:

- name: Pure Storage load balancing example
  hosts: localhost
  gather_facts: no
  vars:
    array_usage: []    # Do not remove - required by the role
  roles:
    - role: lb

  tasks:
  - name: Provisioning to {{ use_name }}
    purefa_volume:
      fa_url: "{{ use_url }}"
      api_token: "{{ use_api }}"
      name: lb_test
      size: 50G

I hope this short post and this role prove useful. If you have any of your own roles or playbooks for Pure Storage devices that you think would be useful to other users, please feel free to contribute them to the ansible-playbook-examples GitHub repository.

Leave a Reply

Your email address will not be published. Required fields are marked *