If you haven’t been made aware, playbooks are now being published to https://www.github.com/netapp-automation/ansible for anyone to use.  Most of the playbooks being posted are what I call lookups.  Lookups use the na_ontap_info module to pull information about one or more elements and report specific information, or to make some decision based on that information.  These can be used as stand-alone examples, or used in your own playbooks.

In this blog post I am going to use two of these posted examples to create a playbook for resizing volumes.  This playbook will only allow resizing to continue if the new size is greater than the used size of the volume, and if the aggregate that the volume is on has enough space for the resize. All this is done with only the login info, vserver, volume name and new size.

Note: ONTAP will not allow you to resize a volume smaller than the used space in it, but the error message is much cleaner using this example.

The two lookups I am going to use to do this are:

  • single_volume_used_free_total_space_report.yml
  • report_specific_aggregate_free_space.yml

Let’s take a look at them here.

single_volume_used_free_total_space_report.yml.
---
- hosts: localhost
  name: Setup ONTAP
  gather_facts: false
  collections:
    - netapp.ontap
  tasks:
  - name: Gather facts
    na_ontap_info:
      state: info
      gather_subset: volume_info
      hostname: "{{ hostname }}"
      vserver: "{{ vserver }}"
      query:
        volume-attributes:
          volume-id-attributes:
            name: '"{{ volname }}"'
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"
    register: netapp_info
  - set_fact:
      used_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_used | int / 1024 / 1024 / 1024) | round }}"
      free_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_available | int / 1024 / 1024 / 1024) | round }}"
      total_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_total | int / 1024 / 1024 / 1024) | round }}"
    with_items: "{{ netapp_info.ontap_info.volume_info }}"
  - debug:
      msg: "{{ used_space }}:{{ free_space }}:{{ total_space}}"

This playbook collects the information about a specific volume represented by the variable ‘volname’, and creates three variables set to the GB sizing for used, free, and total space.  It then will print this information to the screen.

For the playbook I am putting together I only need the “Gather facts” and set_fact tasks, which are lines 8-27 of that playbook.

Here is my resize playbook using these sections.  I then make use of the data along with collecting the aggregate name.

---
- hosts: localhost
  name: Setup ONTAP
  gather_facts: false
  collections:
    - netapp.ontap
  tasks:
  - name: Gather facts
    na_ontap_info:
      state: info
      gather_subset: volume_info
      hostname: "{{ hostname }}"
      vserver: "{{ vserver }}"
      query:
        volume-attributes:
          volume-id-attributes:
            name: '"{{ volname }}"'
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"
    register: netapp_info
  - set_fact:
      used_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_used | int / 1024 / 1024 / 1024) | round }}"
      free_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_available | int / 1024 / 1024 / 1024) | round }}"
      total_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_total | int / 1024 / 1024 / 1024) | round }}"
      aggr_name: "{{ netapp_info.ontap_info.volume_info[item].volume_id_attributes.aggr_list.aggr_name }}"
    with_items: "{{ netapp_info.ontap_info.volume_info }}"
  - fail:
      msg: "Volume used size is greater than new size.  Resizing would corrupt data"
    when: new_size|int < used_size|int

So, with the fail module, if the new_size for my volume is less than the used_size of the volume, the playbook will fail.  The  simple error message will indicate, “Volume used size is greater than new size. Resizing would corrupt data”.

Now I can use the report_specific_aggregate_free_space.yml playbook, which looks like this.

report_specific_aggregate_free_space.yml
---
- hosts: localhost
  name: Setup ONTAP
  gather_facts: false
  collections:
    - netapp.ontap
  tasks:
  - name: Gather aggregate facts
    na_ontap_info:
      gather_subset: aggregate_info
      hostname: "{{ hostname }}"
      query:
        aggr-attributes:
          aggregate-name: '"{{ aggr }}"'
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"
    register: netapp_info
  - set_fact:
      aggr_free: "{{ netapp_info.ontap_info.aggregate_info[aggr].aggr_space_attributes.size_available | int / 1024 / 1024 / 1024 }}"
  - debug:
      msg: "{{ aggr_free }}"

This takes the variable “aggr” and prints it to the screen with its available space in GB.  For my example I am going to change that variable to aggr_name to match the fact I set in the earlier part.  Again, I am just copying the info gather and the set_fact section from this playbook.

Picking up where we left off with the playbook it would look like this.

  - name: Gather aggregate facts
    na_ontap_info:
      gather_subset: aggregate_info
      hostname: "{{ hostname }}"
      query:
        aggr-attributes:
          aggregate-name: '"{{ aggr_name }}"'
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"
    register: netapp_info
  - set_fact:
      aggr_free: "{{ netapp_info.ontap_info.aggregate_info[aggr_name].aggr_space_attributes.size_available | int / 1024 / 1024 / 1024 }}"
  - fail:
      msg: "Containing Aggregate does not have enough free space for resize"
    when: aggr_free|int < (new_size|int - total_size|int)
  - name: Resize Volume "{{ volname }}"
    na_ontap_volume:
      state: present
      name: "{{ volname }}"
      size_unit: gb
      size: "{{ new_size }}"
      size_change_threshold: 0
      vserver: "{{ vserver }}"
      hostname: "{{ hostname }}"
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"

This will now make sure that the volume being increased has enough room to grow within the aggregate it is in.  If it does not the playbook will fail here with the error message “Containing Aggregate does not have enough free space for resize”. Provided no issues exist the playbook will reach the na_ontap_volume task and perform the resize.

Here is the playbook again as one whole piece.

---
- hosts: localhost
  name: Setup ONTAP
  gather_facts: false
  collections:
    - netapp.ontap
  tasks:
  - name: Gather facts
    na_ontap_info:
      gather_subset: volume_info
      hostname: "{{ hostname }}"
      vserver: "{{ vserver }}"
      query:
        volume-attributes:
          volume-id-attributes:
            name: '"{{ volname }}"'
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"
    register: netapp_info
  - set_fact:
      used_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_used | int / 1024 / 1024 / 1024) | round }}"
      free_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_available | int / 1024 / 1024 / 1024) | round }}"
      total_space: "{{ (netapp_info.ontap_info.volume_info[item].volume_space_attributes.size_total | int / 1024 / 1024 / 1024) | round }}"
      aggr_name: "{{ netapp_info.ontap_info.volume_info[item].volume_id_attributes.aggr_list.aggr_name }}"
    with_items: "{{ netapp_info.ontap_info.volume_info }}"
  - fail:
      msg: "Volume used size is greater than new size.  Resizing would corrupt data"
    when: new_size|int < used_size|int
  - name: Gather aggregate facts
    na_ontap_info:
      gather_subset: aggregate_info
      hostname: "{{ hostname }}"
      query:
        aggr-attributes:
          aggregate-name: '"{{ aggr_name }}"'
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"
    register: netapp_info
  - set_fact:
      aggr_free: "{{ netapp_info.ontap_info.aggregate_info[aggr_name].aggr_space_attributes.size_available | int / 1024 / 1024 / 1024 }}"
  - fail:
      msg: "Containing Aggregate does not have enough free space for resize"
    when: aggr_free|int < (new_size|int - total_size|int)
  - name: Resize Volume "{{ volname }}"
    na_ontap_volume:
      state: present
      name: "{{ volname }}"
      size_unit: gb
      size: "{{ new_size }}"
      size_change_threshold: 0
      vserver: "{{ vserver }}"
      hostname: "{{ hostname }}"
      username: "{{ username }}"
      password: "{{ password }}"
      https: "{{ https }}"
      validate_certs: "{{ validate_certs }}"

As you can see it is very easy to grab parts of the shared lookups and use them to make decisions or utilize the information in logic checks when you run playbooks.

I hope this helps you take your playbooks to the next level.  If you have not already joined our Slack workspace get an invite at www.netapp.io/slack and join me and a few of the other module developers on #configurationmgmt with your NetApp Ansible module questions.

David Blackwell on Linkedin
David Blackwell
Technical Marketing Engineer at NetApp
David is a twenty year IT veteran who has been an admin for just about every aspect of a DataCenter at one time or another. When not working, or tinkering with new software at home, David spends most of his free time with his six year old son and his lovely wife.

Pin It on Pinterest