はじめに
本記事ではAnsibleを使ってStorage(ONTAP)を管理する4【変数編2】の続きとして、ONTAP管理の為のインベントリファイルやPlaybook作成に関する内容となります。
今回は範囲は狭いですが、Taskの繰り返しについて記載いたします。
Ansibleではwith_listやwith_itemsのような形でTaskを繰り返し処理を実施していましたが、この記事ではloopに関する内容になります。
何をしたい?できる?
- ONTAPのVolume作成操作の際に、複数Volume作成を1つのPlaybookで実施したい
- Volumeのリストを別ファイルで作成し、Playbookで呼び出して利用したい
- 複数作成したVolumeに複数のQtreeを作成したい(loop利用で作成したい)
loopについて
Ansiblenにおけるloopは、Taskを繰り返し実行するために使用されます。
loopを使用する事でリストや配列などのデータ構造を簡単に反復処理ができ、以下のようにONTAPのVolumeを名前部分だけ変えて複数作成したいような場合に利用できます。

loopへ記載した値を使用する場合は、{{item}}という変数を使います。

また、loop自体の管理としてloop controlが用意されています。
オプション | 説明 |
---|---|
loop_var | loopで指定したリストに変数名をつけ、特に多重繰り返しを実施したい際に利用します。 |
label | loop内の特定の値をラベルとして定義します |
pause | loopの実行間隔を指定します(秒単位) |
index_var | loopされる回数をインデックス表示します |
extended | trueを指定する事で、拡張loop変数を利用できるようになります。 |
記事における環境情報
本記事では、以下の環境で実施した内容となります。
- Rocky Linux : 9.1
- Python : 3.9.14
- Ansible (Core): 2.14.1
- netapp-lib : 2021.6.25
- netapp.ontap : 22.1.0
環境のイメージとしては以下の通りです。
![]() |
---|
設定手順
まずは、Playbook内にloopで利用する複数のVolume名を記載して挙動を確認してみます。
そして、別ファイルに作成する複数のVolume名を記載し動作するのか確認し、最後に多重繰り返しを実施してVolumenへのQtree作成を実施します。
1. インベントリファイルの確認
以下のような形でインベントリファイルを記載しています。
- 全ホストはallというグループに所属
> cat inventory.yml
---
all:
hosts:
Ansible:
ansible_host: 172.16.10.180
Linux:
ansible_host: 172.16.10.148
...
2. Playbook内にloopを記載して作成
ここでは以下の名前部分のみ変更されてVolume作成を繰り返すPalybookを作成します。
・vol101とvol102というVolumeを2つ作成
・Volume名とJinctuionPathは同じ名前にする
> cat playbook_volume_create.yml
---
- name: Create volume on ONTAP SVM
hosts: localhost
connection: local
gather_facts: false
vars:
svm_host: 172.16.10.147
svm_user: testuser
svm_password: XXXXXXX
svm_protocol: https
vserver: cifs100
size: 5
size_unit: gb
aggregate_name: aggr1_node2
export_policy: default
tasks:
- name: Create volume
na_ontap_volume:
state: present
hostname: "{{ svm_host }}"
username: "{{ svm_user }}"
password: "{{ svm_password }}"
https: "{{ svm_protocol == 'https' }}"
vserver: "{{ vserver }}"
size: "{{ size }}"
size_unit: "{{ size_unit }}"
aggregate_name: "{{ aggregate_name }}"
name: "{{ item }}"
junction_path: "/{{ item }}"
export_policy: "{{ export_policy }}"
validate_certs: false
use_rest: Always
loop:
- vol101
- vol102
3. Playbookの実行
Playbookに記載されているvol101, vol102の作成が実施されます。
> ansible-playbook -i inventory.yml -u user01 playbook_volume_create.yml --ask-pass
SSH password:
PLAY [Create volume on ONTAP SVM] ***************************************************************************************************
TASK [Create volume] ****************************************************************************************************************
changed: [localhost] => (item=vol101)
changed: [localhost] => (item=vol102)
PLAY RECAP **************************************************************************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Storage側からも作成が確認できます。
> volume show -fields volume,junction-path
vserver volume junction-path
------- ------------ -------------
cifs100 cifs100_root /
cifs100 vol101 /vol101
cifs100 vol102 /vol102
3 entries were displayed.
4. 値をハッシュリストとして参照してPlaybookの実行
ここでは以下の内容で繰り返すものを作成します。
・vol101とvol102というVolumeを2つ作成
・Volume名とJinctuionPathは別の名前にする
(vol101のPathを/cifs101のような形)
実現する為にloop部分にハッシュリストで値を記載し、Subキーを参照することができます。
(item.nameやitem.pathのような形で値を参照できる)
> cat playbook_volume_create2.yml
---
- name: Create volume on ONTAP SVM
hosts: localhost
connection: local
gather_facts: false
vars:
svm_host: 172.16.10.147
svm_user: testuser
svm_password: XXXXXX
svm_protocol: https
vserver: cifs100
size: 5
size_unit: gb
aggregate_name: aggr1_node2
export_policy: default
tasks:
- name: Create volume
na_ontap_volume:
state: present
hostname: "{{ svm_host }}"
username: "{{ svm_user }}"
password: "{{ svm_password }}"
https: "{{ svm_protocol == 'https' }}"
vserver: "{{ vserver }}"
size: "{{ size }}"
size_unit: "{{ size_unit }}"
aggregate_name: "{{ aggregate_name }}"
name: "{{ item.name }}"
junction_path: "/{{ item.path }}"
export_policy: "{{ export_policy }}"
validate_certs: false
use_rest: Always
loop:
- {name: 'vol101', path: 'cifs101'}
- {name: 'vol102', path: 'cifs102'}
Volumeの作成を実行します。
> ansible-playbook -i inventory.yml -u user01 playbook_volume_create2.yml --ask-pass
SSH password:
PLAY [Create volume on ONTAP SVM] ***************************************************************************************************
TASK [Create volume] ****************************************************************************************************************
changed: [localhost] => (item={'name': 'vol101', 'path': 'cifs101'})
changed: [localhost] => (item={'name': 'vol102', 'path': 'cifs102'})
PLAY RECAP **************************************************************************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Storage側からも作成が確認できます。
> volume show -fields volume,junction-path
vserver volume junction-path
------- ------------ -------------
cifs100 cifs100_root /
cifs100 vol101 /cifs101
cifs100 vol102 /cifs102
3 entries were displayed.
5. 外部ファイルにloopする変数を記載してPlaybookの実行
ここでは以下の内容で繰り返すものを作成します。
・vol101とvol102というVolumeを2つ作成
・Volume名とJinctuionPathはPlaybookとは別のファイルに記載
・Volume名とJinctuionPathは別の名前にする
(vol101のPathを/cifs101のような形)
まず、Volume名とJinctuionPathを記載したファイル(loop_data.yml)を作成します。
> cat loop_data.yml
---
volumes:
- {name: 'vol101', path: 'cifs101'}
- {name: 'vol102', path: 'cifs102'}
Playbookは以下のように記載します。
- taskにinclude_varsを追記して、作成した変数記載ファイルの指定
- loopの後に "{{ volumes }}"という変数記載ファイル内のディレクティブ(キーワード)を記載
> cat playbook_volume_create3.yml
---
- name: Create volume on ONTAP SVM
hosts: localhost
connection: local
gather_facts: false
vars:
svm_host: 172.16.10.147
svm_user: testuser
svm_password: XXXXXXX
svm_protocol: https
vserver: cifs100
size: 5
size_unit: gb
aggregate_name: aggr1_node2
export_policy: default
tasks:
- name: include_vars
include_vars:
file: loop_data.yml
- name: Create volume
na_ontap_volume:
state: present
hostname: "{{ svm_host }}"
username: "{{ svm_user }}"
password: "{{ svm_password }}"
https: "{{ svm_protocol == 'https' }}"
vserver: "{{ vserver }}"
size: "{{ size }}"
size_unit: "{{ size_unit }}"
aggregate_name: "{{ aggregate_name }}"
name: "{{ item.name }}"
junction_path: "/{{ item.path }}"
export_policy: "{{ export_policy }}"
validate_certs: false
use_rest: Always
loop: "{{ volumes }}"
Volumeの作成を実行します。
> ansible-playbook -i inventory.yml -u user01 playbook_volume_create3.yml --ask-pass
SSH password:
PLAY [Create volume on ONTAP SVM] ***************************************************************************************************
TASK [include_vars] *****************************************************************************************************************
ok: [localhost]
TASK [Create volume] ****************************************************************************************************************
changed: [localhost] => (item={'name': 'vol101', 'path': 'cifs101'})
changed: [localhost] => (item={'name': 'vol102', 'path': 'cifs102'})
PLAY RECAP **************************************************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
6. loop_controlによる多重繰り返し(Qtree作成部分)
ここでは以下の内容で繰り返すものを作成します。
・vol101とvol102というVolumeを2つ作成
・各Volumeにtree01, tree02, tree03というQtreeを作成(Security Styleは夫々変える)
・loop_varを利用して多重繰り返し
・Qtree作成タスクは別ファイル(qtree_create.yml)で作成
・Volume名とJinctuionPathやQtree名等はPlaybookとは別のファイルに記載
・Volume名とJinctuionPathは別の名前にする
(vol101のPathを/cifs101のような形)
まず、Volume名やQtree名を記載したファイル(loop_data.yml)を作成します。
> cat loop_data.yml
---
volumes:
- {name: 'vol101', path: 'cifs101'}
- {name: 'vol102', path: 'cifs102'}
qtrees:
- {name: 'tree01', security_style: 'ntfs'}
- {name: 'tree02', security_style: 'unix'}
- {name: 'tree03', security_style: 'ntfs'}
Playbookは以下のように記載します。
- taskにinclude_varsを追記して、作成した変数記載ファイルの指定
- Volume作成taskのloopの後に "{{ volumes }}"という変数記載ファイル内のディレクティブ(キーワード)を記載
- qtree_create.ymlというQtree作成taskは別ファイルで作成
- qtree_create.ymlを呼び出して実行するtaskのloopの後に "{{ qtrees }}"を指定
- loop_controlでloop_varを使用し、qtreeという変数名にする

Qtree作成用の別ファイルは以下の通りです。
> cat qtree_create.yml
- name: Create Qtree
na_ontap_qtree:
state: present
hostname: "{{ svm_host }}"
username: "{{ svm_user }}"
password: "{{ svm_password }}"
https: "{{ svm_protocol == 'https' }}"
vserver: "{{ vserver }}"
name: "{{ qtree.name }}"
flexvol_name: "{{ item.name }}"
security_style: "{{ qtree.security_style }}"
validate_certs: false
use_rest: Always
loop: "{{ volumes }}"
Ansibleコマンド実行の際に指定するplaybookは以下の通りです。
> cat playbook_volume_create4.yml
---
- name: Create volume on ONTAP SVM
hosts: localhost
connection: local
gather_facts: false
vars:
svm_host: 172.16.10.147
svm_user: testuser
svm_password: XXXXXX
svm_protocol: https
vserver: cifs100
size: 5
size_unit: gb
aggregate_name: aggr1_node2
export_policy: default
tasks:
- name: include_vars
include_vars:
file: loop_data.yml
- name: Create volume
na_ontap_volume:
state: present
hostname: "{{ svm_host }}"
username: "{{ svm_user }}"
password: "{{ svm_password }}"
https: "{{ svm_protocol == 'https' }}"
vserver: "{{ vserver }}"
size: "{{ size }}"
size_unit: "{{ size_unit }}"
aggregate_name: "{{ aggregate_name }}"
name: "{{ item.name }}"
junction_path: "/{{ item.path }}"
export_policy: "{{ export_policy }}"
validate_certs: false
use_rest: Always
loop: "{{ volumes }}"
- name: Include Create Qtrees
include_tasks: qtree_create.yml
loop: "{{ qtrees }}"
loop_control:
loop_var: qtree
Volumeの作成を実行します。
> ansible-playbook -i inventory.yml -u user01 playbook_volume_create4.yml --ask-pass
SSH password:
PLAY [Create volume on ONTAP SVM] ***************************************************************************************************
TASK [include_vars] *****************************************************************************************************************
ok: [localhost]
TASK [Create volume] ****************************************************************************************************************
changed: [localhost] => (item={'name': 'vol101', 'path': 'cifs101'})
changed: [localhost] => (item={'name': 'vol102', 'path': 'cifs102'})
TASK [Include Create Qtrees] ********************************************************************************************************
included: /home/ansible_user10/ansible_work5/qtree_create.yml for localhost => (item={'name': 'tree01', 'security_style': 'ntfs'})
included: /home/ansible_user10/ansible_work5/qtree_create.yml for localhost => (item={'name': 'tree02', 'security_style': 'unix'})
included: /home/ansible_user10/ansible_work5/qtree_create.yml for localhost => (item={'name': 'tree03', 'security_style': 'ntfs'})
TASK [Create Qtree] *****************************************************************************************************************
changed: [localhost] => (item={'name': 'vol101', 'path': 'cifs101'})
changed: [localhost] => (item={'name': 'vol102', 'path': 'cifs102'})
TASK [Create Qtree] *****************************************************************************************************************
changed: [localhost] => (item={'name': 'vol101', 'path': 'cifs101'})
changed: [localhost] => (item={'name': 'vol102', 'path': 'cifs102'})
TASK [Create Qtree] *****************************************************************************************************************
changed: [localhost] => (item={'name': 'vol101', 'path': 'cifs101'})
changed: [localhost] => (item={'name': 'vol102', 'path': 'cifs102'})
PLAY RECAP **************************************************************************************************************************
localhost : ok=8 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Storage側からも作成が確認できます。
> volume show -fields volume,junction-path
vserver volume junction-path
------- ------------ -------------
cifs100 cifs100_root /
cifs100 vol101 /cifs101
cifs100 vol102 /cifs102
3 entries were displayed.
> qtree show
Vserver Volume Qtree Style Oplocks Status
---------- ------------- ------------ ------------ --------- --------
cifs100 cifs100_root "" ntfs enable normal
cifs100 vol101 "" ntfs enable normal
cifs100 vol101 tree01 ntfs enable normal
cifs100 vol101 tree02 unix enable normal
cifs100 vol101 tree03 ntfs enable normal
cifs100 vol102 "" ntfs enable normal
cifs100 vol102 tree01 ntfs enable normal
cifs100 vol102 tree02 unix enable normal
cifs100 vol102 tree03 ntfs enable normal
9 entries were displayed.
参考及びリンク
Ansibleを使ってStorage(ONTAP)を管理する1 【Rocky LinuxへAnsible Install編】
Ansibleを使ってStorage(ONTAP)を管理する2【ChatGPTでVolume作成用Playbookを作成】