HPE Storage Tech Insiders
Showing results for 
Search instead for 
Did you mean: 

NimbleOS loves Ansible


If I end setting up the same thing twice or need to step through a tedious workflow I tend to find myself looking to Ansible for pain relief. I've picked Ansible as my configuration management tool of choice as I can bend it to do whatever I like to anything I like with a language I can read and understand.

Ansible is written in Python and as with all things Python, Ansible is available in the Python Package Index (PyPi), on a node where pip is installed, simply run:

$ pip install ansible

Comprehensive documentation about Ansible is available on docs.ansible.com.

Today I was delighted to discover that the built-in URI module is capable of manipulating NimbleOS arrays via the comprehensive REST API (check it out on InfoSight!). Needless to say, we now have a fully fledged orchestration tool at our disposal!

I'm currently doing a lot testing of an upcoming and exciting Nimble Storage offering and find myself with an array completely cluttered with volumes in all shapes and sizes. I wanted to revert my array to a clean state without disrupting the rest of my configuration and volumes not affected by these tests. The volumes I want to get rid of have two distinct features: they are offline and the volume name contains a specific string. Challenge accepted.

The following Ansible playbook (it's a YAML file, attached below) contains some commentary of what some of the interesting parameters are doing (for clarity, I've put the entire workflow in one playbook):

# volume-reaper.yml


# We will use this node to interface with my Nimble Storage Group

- hosts: localhost

  # Since our array is remote, we don't care about collecting local facts

  gather_facts: no

  # Variables local for this play


    base_url: https://nimble-array.local:5392/v1

    username: admin

    password: admin


  # First we need a token to be able to use the APIs

  - name: Get API token


      url: "{{ vars.base_url }}/tokens"

      validate_certs: no

      method: POST

      # This is the HTTP status code that designates success

      status_code: 201


      # This ensures the correct Content-Type header is set

      body_format: json

      # The following structure will be converted to JSON on the fly



         username: "{{ vars.username }}"

         password: "{{ vars.password }}"

      # We want to access the content we retrieve

      return_content: yes

    # The returned data JSON object will be accessible in the token dictionary

    register: token

  # List all the volumes

  - name: Fetch all volumes and metadata


      url: "{{ vars.base_url }}/volumes/detail?fields=name,online,id"

      method: GET

      validate_certs: no

      status_code: 200

      return_content: yes

      # Here's the token we got from a successful login above

      HEADER_X-Auth-Token: "{{ token.json.data.session_token }}"

    # All volume data is accessible through the volume dictionary

    register: volumes

  - name: Destroy Volumes if offline and contains the name MyTestVol


      url: "{{ vars.base_url }}/volumes/{{ item.id }}"

      method: DELETE

      validate_certs: no

      status_code: 200

      return_content: yes

      HEADER_X-Auth-Token: "{{ token.json.data.session_token }}"

    # This task will iterate over all volumes

    with_items: "{{ volumes.json.data }}"

    # ... but only execute the task if the volume name contains MyTestVol and is offline

    when: "('MyTestVol' in item.name and not item.online)"

    # Note: The condition in the when: statement is a Jinja2 expression

So, to simply wipe my array from offline volumes that contains the keyword 'MyTestVol' in the volume name, one would simply run:

$ ansible-playbook volume-reaper.yml

[WARNING]: provided hosts list is empty, only localhost is available

PLAY [localhost] ***************************************************************

TASK [Get API token] ***********************************************************

ok: [localhost]

TASK [Fetch all volumes and metadata] ******************************************

ok: [localhost]

TASK [Destroy Volumes if offline and contains the name MyTestVol] *****************

skipping: [localhost] => (item={u'id': u'0633cfd76905aa2a50000000000000000000000016', u'name': u'MyProdVol3', u'online': True})

ok: [localhost] => (item={u'id': u'0633cfd76905aa2a5000000000000000000000001d', u'name': u'MyTestVol40', u'online': False})

skipping: [localhost] => (item={u'id': u'0633cfd76905aa2a5000000000000000000000001b', u'name': u'MyProdVol2', u'online': True})

PLAY RECAP *********************************************************************

localhost                  : ok=3    changed=0    unreachable=0    failed=0

$ _

Until there is a bleeding need for a native NimbleOS Ansible module, this will more than suffice for most use cases. Please note, for this particular Ansible playbook I was using NimbleOS 3.3, earlier versions have not been tested.

Please tell me what you automated today.


About the Author


Data & Storage Nerd, Containers, DevOps, IT Automation


Great post!  Thanks for the details on how to get this going.

Apr 24 - 25, 2018
Expert Days - 2018
Visit this forum and get the schedules for online HPE Expert Days where you can talk to HPE product experts, R&D and support team members and get answ...
Read more
June 19 - 21
Las Vegas, NV
HPE Discover 2018 Las Vegas
Visit this forum and learn about all things Discover 2018 in Las Vegas, Nevada, June 19 - 21, 2018.
Read more
View all