Sometimes it is useful to create a single playbook or role that does multiple steps, but not steps you want to run every time.  You can use ‘tags’ to only include or exclude certain tasks in a playbook.  To look at this concept I will use a playbook for creating SnapMirror relationships and performing failovers.  This can be used to create DR sets for volumes and testing them as well.  Here is the playbook.

 

 1. ---
 2. - hosts: localhost
 3.  name: Disaster Recovery
 4.  collections:
 5.  - netapp.ontap
 6.  gather_facts: false
 7.  vars:
 8.    login: &login
 9.     username: "{{ username }}"
10.      password: "{{ password }}"
11.      https: "{{ https }}"
12.      validate_certs: "{{ validate_certs }}"
13.  tasks:
14.  # tasks file for dr
15.  - name: Gather volume facts
16.    na_ontap_info:
17.      gather_subset: volume_info
18.      hostname: "{{ hostname }}"
19.      <<: *login
20.    register: netapp_info
21.    tags: create
22.  - set_fact:
23.      size: "{{ netapp_info.ontap_info.volume_info[item].volume_space_attributes.size |int / 1024 / 1024 / 1024 | round(0,'ceil') | int }}"
24.   with_items: "{{ netapp_info.ontap_info.volume_info }}"
25.   when:
26.   - netapp_info.ontap_info.volume_info[item].volume_id_attributes.owning_vserver_name == src_vserver
27.   - netapp_info.ontap_info.volume_info[item].volume_id_attributes.name == src_volume
28.   tags: create
29. - name: Gather aggregate facts
30.   na_ontap_info:
31.     gather_subset: aggregate_info
32.     hostname: "{{ dst_hostname }}"
33.     <<: *login
34.   register: netapp_info
35.   tags: create
36. - set_fact:
37.     aggr_name: "{{ item }}"
38.   with_items: "{{ netapp_info.ontap_info.aggregate_info }}"
39.   when:
40.   - aggr_name is not defined
41.   - "{{ netapp_info.ontap_info.aggregate_info[item].aggr_space_attributes.size_available | int / 1024 / 1024 / 1024 }}  > {{ size }}"
42.   - netapp_info.ontap_info.aggregate_info[item].aggr_raid_attributes.is_root_aggregate == 'false'
43.   tags: create
44. - name: Validate destination FlexVol
45.   na_ontap_volume:
46.     state: present
47.     name: "{{ dst_volume }}"
48.     aggregate_name: "{{ aggr_name }}"
49.     size: "{{ size | int | string }}"
50.     size_unit: gb
51.     type: DP    
52.     vserver: "{{ dst_vserver }}"
53.     hostname: "{{ dst_hostname }}"
54.     <<: *login
55.   tags: create
56. - name: Create SnapMirror
57.   na_ontap_snapmirror:
58.     state: present
59.     source_volume: "{{ src_volume }}"
60.     destination_volume: "{{ dst_volume }}"
61.     source_vserver: "{{ src_vserver }}"
62.     destination_vserver: "{{ dst_vserver }}"
63.     hostname: "{{ dst_hostname }}"
64.     <<: *login
65.   tags: create,resync
66. - name: Break off SnapMirror
67.   na_ontap_snapmirror:
68.     state: present
69.     source_volume: "{{ src_volume }}"
70.     destination_volume: "{{ dst_volume }}"
71.     source_vserver: "{{ src_vserver }}"
72.     destination_vserver: "{{ dst_vserver }}"
73.    relationship_state: broken
74.     hostname: "{{ dst_hostname }}"
75.     <<: *login
76.   tags: break
77. - name: reverse sync SnapMirror
78.   na_ontap_snapmirror:
79.     state: present
80.     source_volume: "{{ dst_volume }}"
81.     destination_volume: "{{ src_volume }}"
82.     source_vserver: "{{ dst_vserver }}"
83.     destination_vserver: "{{ src_vserver }}"
84.     hostname: "{{ hostname }}"
85.     <<: *login
86.   tags: reverse

This playbook includes ‘tags’, or meta sections for each task.  These allow only part of the playbook to be called.  In fact, the way this playbook is written, trying to run it without calling tasks would cause severe errors since it would try creating, breaking, and reversing the SnapMirror relationship in a single run.

Look at lines 21,28,35,43,55,65,76,86 in the playbook.  These are the tags that I have specified.  Running a specific tag is easy and it’s done with –tags, or to skip tags the –skip-tags command switches like this:

ansible-playbook backup.yml --tags create

This will run the playbook but only execute tasks that have the ‘create’ tag.  You can assign multiple tags to a task by using comma separation, just as you can specify multiple tags on the command line the same way.

For my example playbook, I have a vars.yml variable file that looks like this

aggr_type: hdd
src_vserver: ansible_svm_src
src_volume: share02
dst_volume: "{{ src_volume }}_dest"
dst_vserver: ansible_svm_dst
dst_hostname: 192.168.12.52
hostname: 192.168.12.51
username: admin
password: netapp123
https: true
validate_certs: false

The aggr_type is to only check for Aggregates that have hdd disks, I could use ssd if I wanted that. Variables that start with ‘src’ are for the source cluster and ‘dst’ for the destination cluster.  This assumes both clusters have the same admin user and password.  Specifying the appropriate tag, I can create the SnapMirror relationship like this:

ansible-playbook backup.yml -e @vars.yml --tags create

Using the ‘break’ tag allows me to test my SnapMirror destination without destroying the relationship.  The tag ‘resync’ will start the SnapMirror up again, and ‘reverse’ will send the SnapMirror in the opposite direction from destination to source as in the case of a pro-longed DR event.  BE AWARE – If you use this specific example, after the reverse you will need to switch the src and dest entries in your variable file for the playbook to still work.

I hope this example of tags in a DR situation helps you come up with other uses and makes your Ansible experiences even better.  If you haven’t already joined our Slack workspace do so at www.netapp.io/slack and join us in the #configurationmgmt channel.

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