ONTAP: Use Ansible to Provision SAN Storage

A great way to gain understanding of Ansible (or any language for that matter) is seeing code examples. The Ansible documentation links below also have code examples.

Table of Contents

  1. References
  2. san_playbook_v1
    1. What it does
    2. Vars File
    3. Playbook
    4. Running the Playbook
  3. Using Roles
    1. Folder Structure
    2. provision_san role: main.yml files
      1. meta > main.yml file
      2. tasks > main.yml file
      3. vars > main.yml file
    3. Example Playbook Using the provision_san Role
    4. Running the Playbook

1. References

References to the NetApp ONTAP Ansible modules used in this post:

2. san_playbook_v1

2.1. What it does

Create Volume for LUN
Create LUN
Create Initiator Group
Add Initiator to Initiator Group
Map LUN to Initiator Group

2.2. Vars File

san_vars.yml

netapp_hostname: cluster1.acompany.com
netapp_username: admin
vserver: svm2_cluster1
aggr_name: cluster1_02_SSD_1

volname: vol3
size: 50

lun_name: lun1
lun_size: 20

ostype: windows
initiator_name: iqn.1991-05.com.microsoft:testbox.acompany.com
igroup_name: lun_igroup_1
igroup_type: iscsi


2.3. Playbook

san_playbook.yml

---
- hosts: localhost
  gather_facts: false
  name: Provision SAN Storage
  collections:
    - netapp.ontap

  module_defaults:
    group/netapp.ontap.netapp_ontap:
      hostname: "{{ netapp_hostname }}"
      username: "{{ netapp_username }}"
      password: "{{ netapp_password }}"
      vserver: "{{ vserver }}"
      https: true
      validate_certs: false
      use_rest: auto
  vars_prompt:
    - name: "netapp_password"
      prompt: "Enter the NetApp Admin Password"
      private: true
      confirm: true
  vars_files:
    - ./san_vars.yml

  tasks:
  
    - name: Create Volume for LUN
      na_ontap_volume:
        state: present
        name: "{{ volname }}"
        aggregate_name: "{{ aggr_name }}"
        size: "{{ size }}"
        size_unit: gb
        space_guarantee: "none"
        volume_security_style: unix

    - name: Create LUN
      na_ontap_lun:
        state: present
        name: "{{ lun_name }}"
        flexvol_name: "{{ volname }}"
        size: "{{ lun_size }}"
        size_unit: gb
        ostype: "{{ ostype }}"
        space_reserve: true

    - name: Create Initiator Group
      na_ontap_igroup:
        state: present
        name: "{{ igroup_name }}"
        initiator_group_type: "{{ igroup_type }}"
        os_type: "{{ ostype }}"

    - name: Add Initiator to Initiator Group
      na_ontap_igroup_initiator:
        state: present
        initiator_group: "{{ igroup_name }}"
        names: "{{ initiator_name }}"

    - name: Map LUN to Initiator Group
      na_ontap_lun_map:
        state: present
        initiator_group_name: "{{ igroup_name }}"
        path: "/vol/{{ volname }}/{{ lun_name }}"

2.4. Running the Playbook

ansible@ansible:~$ ansible-playbook san_playbook.yml


After running this Ansible playbook, you will need to mount the LUN on the host and do any required host side formatting before the LUN is ready for use. This is something that could be done in Ansible too.

3. Using Roles

For reuse-ability, using roles is the recommended way of doing things:

Ansible - Roles (tutorialspoint.com) 

"Roles provide a framework for fully independent, or interdependent collections of variables, tasks, files, templates, and modules.

"In Ansible, the role is the primary mechanism for breaking a playbook into multiple files. This simplifies writing complex playbooks, and it makes them easier to reuse. The breaking of playbook allows you to logically break the playbook into reusable components."

3.1. Folder Structure

In the roles folder, we create our role folder (our role) called - provision_san - and 3 folders inside that folder - meta, tasks, vars. Each of the 3 sub-folders has a main.yml file.

  • roles
    • provision_san
      • meta
        • main.yml
      • tasks
        • main.yml
      • vars
        • main.yml

3.2. provision_san role: main.yml files

3.2.1. meta > main.yml file


collections:
  - netapp.ontap


3.2.2. tasks > main.yml file


---
- name: Create Volume for LUN
  na_ontap_volume:
    state: present
    hostname: "{{ netapp_hostname }}"
    username: "{{ netapp_username }}"
    password: "{{ netapp_password }}"
    vserver: "{{ vserver }}"
    https: true
    validate_certs: false
    use_rest: auto
    name: "{{ volname }}"
    aggregate_name: "{{ aggr_name }}"
    size: "{{ size }}"
    size_unit: gb
    space_guarantee: "none"
    volume_security_style: unix

- name: Create LUN
  na_ontap_lun:
    state: present
    hostname: "{{ netapp_hostname }}"
    username: "{{ netapp_username }}"
    password: "{{ netapp_password }}"
    vserver: "{{ vserver }}"
    https: true
    validate_certs: false
    use_rest: auto
    name: "{{ lun_name }}"
    flexvol_name: "{{ volname }}"
    size: "{{ lun_size }}"
    size_unit: gb
    ostype: "{{ ostype }}"
    space_reserve: true

- name: Create Initiator Group
  na_ontap_igroup:
    state: present
    hostname: "{{ netapp_hostname }}"
    username: "{{ netapp_username }}"
    password: "{{ netapp_password }}"
    vserver: "{{ vserver }}"
    https: true
    validate_certs: false
    use_rest: auto
    name: "{{ igroup_name }}"
    initiator_group_type: "{{ igroup_type }}"
    os_type: "{{ ostype }}"

- name: Add Initiator to Initiator Group
  na_ontap_igroup_initiator:
    state: present
    hostname: "{{ netapp_hostname }}"
    username: "{{ netapp_username }}"
    password: "{{ netapp_password }}"
    vserver: "{{ vserver }}"
    https: true
    validate_certs: false
    use_rest: auto
    initiator_group: "{{ igroup_name }}"
    names: "{{ initiator_name }}"

- name: Map LUN to Initiator Group
  na_ontap_lun_map:
    state: present
    hostname: "{{ netapp_hostname }}"
    username: "{{ netapp_username }}"
    password: "{{ netapp_password }}"
    vserver: "{{ vserver }}"
    https: true
    validate_certs: false
    use_rest: auto
    initiator_group_name: "{{ igroup_name }}"
    path: "/vol/{{ volname }}/{{ lun_name }}"

3.2.3. vars > main.yml file


netapp_hostname: cluster1.yourcompany.com
netapp_username: admin
vserver: svm2_cluster1
aggr_name: cluster1_02_SSD_1

ostype: windows
igroup_name: lun_igroup_1
igroup_type: iscsi

3.3. Example Playbook Using the provision_san Role

This runbook calls the provision_san role once.

provision_san.yml


- hosts: localhost
  gather_facts: false

  vars_prompt:
    - name: "netapp_password"
      prompt: "Enter the NetApp Admin Password"
      private: true
      confirm: true
  
  roles:
    - role: provision_san
      volname: vol8
      size: 20
      lun_name: lun2
      lun_size: 10
      initiator_name: iqn.1991-05.com.microsoft:testhost.yourcompany.com

3.4. Running the Playbook

ansible@ansible:~$ ansible-playbook provision_san.yml


Comments