ホーム > Ansible Tower・AWX リファレンス
Ansibleも他言語と同様にループ処理を実装することが可能です。ここでは、実例を交えながらループ処理の記述方法を解説したいと思います。
Ansibleでのループ処理は、他言語でよく見かける For~文ではなく、「with_~」ディレクティブを使用します。
前回に引き続き、今回は以下のディレクティブを解説します。
with_subelements:配列のサブ要素を元にループ
with_subelements は、配列のサブ要素を元にしてループを行います。
他のループより少し分かりにくいループ処理ですが、意外に使用頻度は高いです。
書式
with_subelements の書式です。
with_subelements: - 配列 - 配列のサブ要素
プレイブック
サンプルのプレイブックです。
---
- hosts: all
gather_facts: False
tasks:
- name: 配列の作成
set_fact:
deploy_info:
- process: tomcat001
module:
- foo.war
- bar.war
- process: tomcat002
module:
- tomcat.war
- root.war
- name: ループ処理【with_subelements】
debug:
msg: "{{ item.0.process }}/{{ item.1 }}"
with_subelements:
- "{{ deploy_info }}"
- module
まず、配列を作成していますが、これは「with_subelements」で使用するテスト用の配列を作成しています。
タスク「ループ処理」では、with_subelementsのインプットとなる配列[deploy_info]の要素と、そのサブ要素[module]でループが行われます。
これだけではイメージが難しいと思うので、ここからさらに砕いて解説していきます。
今回実行したプレイブックで表示している情報は「msg: “{{ item.0.process }}/{{ item.1 }}”」となっています。
この「item.0.process」と「item.1」は、下記のように配列と紐づいています。
下記が実行結果の一部です。
with_subelements の配列「deploy_info」の要素が2つ、そのサブ要素の「module」の要素が2つなので、2×2で4回ループされています。
TASK [ループ処理【with_subelements】] ************************************************* ok: [192.168.56.105] => (item=[{'process': 'tomcat001'}, 'foo.war']) => { "msg": "tomcat001/foo.war" } ok: [192.168.56.105] => (item=[{'process': 'tomcat001'}, 'bar.war']) => { "msg": "tomcat001/bar.war" } ok: [192.168.56.105] => (item=[{'process': 'tomcat002'}, 'tomcat.war']) => { "msg": "tomcat002/tomcat.war" } ok: [192.168.56.105] => (item=[{'process': 'tomcat002'}, 'root.war']) => { "msg": "tomcat002/root.war" }
ループ回数と配列を表にすると下記のようになります。
ループ回数 | item.0.process | item.1 |
---|---|---|
1周目 | tomcat001 | foo.war |
2周目 | tomcat001 | bar.war |
3周目 | tomcat002 | tomcat.war |
4周目 | tomcat002 | root.war |
実行結果
サンプルのプレイブックを実行した結果になります。
SSH password:
BECOME password[defaults to SSH password]:
PLAY [all] *********************************************************************
TASK [配列の作成] *******************************************************************
ok: [192.168.56.105]
TASK [ループ処理【with_subelements】] *************************************************
ok: [192.168.56.105] => (item=[{'process': 'tomcat001'}, 'foo.war']) => {
"msg": "tomcat001/foo.war"
}
ok: [192.168.56.105] => (item=[{'process': 'tomcat001'}, 'bar.war']) => {
"msg": "tomcat001/bar.war"
}
ok: [192.168.56.105] => (item=[{'process': 'tomcat002'}, 'tomcat.war']) => {
"msg": "tomcat002/tomcat.war"
}
ok: [192.168.56.105] => (item=[{'process': 'tomcat002'}, 'root.war']) => {
"msg": "tomcat002/root.war"
}
PLAY RECAP *********************************************************************
192.168.56.105 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_nested:複数のリストを総当たりするようにループ
with_nested は、複数のリストの要素を総当たりのように組み合わせてループを行います。
書式
with_nested の書式です。
リストの数は3つ以上でも可能ですが、あまり多くするとログ出力が大量になります。
with_nested: - リスト1 - リスト2
プレイブック
サンプルのプレイブックです。
---
- hosts: all
gather_facts: False
tasks:
- name: ループ処理【with_nested】
debug:
msg: "{{ item }}"
with_nested:
- ["one", "two"]
- ["要素1", "要素2", "要素3"]
このプレイブックでは、下記の2つのリストでループしています。
・リスト1(要素2つ):[“one”, “two”]
・リスト2(要素3つ):[“要素1”, “要素2”, “要素3”]
上記を組み合わせて実行されるループは以下のようになります。
ループ回数 | 組み合わせ |
---|---|
1周目 | one, 要素1 |
2周目 | one, 要素2 |
3周目 | one, 要素3 |
4周目 | two, 要素1 |
5周目 | two, 要素2 |
6周目 | two, 要素3 |
下記は実行結果の一部で、先程の組み合わせのように実行されていることが分かります。
TASK [ループ処理【with_nested】] ****************************************************** ok: [192.168.56.105] => (item=['one', '要素1']) => { "msg": [ "one", "要素1" ] } ok: [192.168.56.105] => (item=['one', '要素2']) => { "msg": [ "one", "要素2" ] } ok: [192.168.56.105] => (item=['one', '要素3']) => { "msg": [ "one", "要素3" ] } ok: [192.168.56.105] => (item=['two', '要素1']) => { "msg": [ "two", "要素1" ] } ok: [192.168.56.105] => (item=['two', '要素2']) => { "msg": [ "two", "要素2" ] } ok: [192.168.56.105] => (item=['two', '要素3']) => { "msg": [ "two", "要素3" ] }
実行結果
サンプルのプレイブックを実行した結果になります。
SSH password:
BECOME password[defaults to SSH password]:
PLAY [all] *********************************************************************
TASK [ループ処理【with_nested】] ******************************************************
ok: [192.168.56.105] => (item=['one', '要素1']) => {
"msg": [
"one",
"要素1"
]
}
ok: [192.168.56.105] => (item=['one', '要素2']) => {
"msg": [
"one",
"要素2"
]
}
ok: [192.168.56.105] => (item=['one', '要素3']) => {
"msg": [
"one",
"要素3"
]
}
ok: [192.168.56.105] => (item=['two', '要素1']) => {
"msg": [
"two",
"要素1"
]
}
ok: [192.168.56.105] => (item=['two', '要素2']) => {
"msg": [
"two",
"要素2"
]
}
ok: [192.168.56.105] => (item=['two', '要素3']) => {
"msg": [
"two",
"要素3"
]
}
PLAY RECAP *********************************************************************
192.168.56.105 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_cartesian:複数のリストを総当たりするようにループ
with_nested と同じ処理なので、with_nested をご覧ください。
with_random_choice:リストの要素から1つを選択してループ
with_random_choice は、指定したリストから、要素を1つランダムに選択し、それを元にしてループを行います。
書式
with_random_choice の書式です。
with_random_choice: リスト
プレイブック
サンプルのプレイブックです。
---
- hosts: all
gather_facts: False
tasks:
- name: リストの作成
set_fact:
list:
- "要素0"
- "要素1"
- "要素2"
- name: ループ処理【with_random_choice】
debug:
msg: "{{ item }}"
with_random_choice: "{{ list }}"
このプレイブックでは、まずループに使用するリストを作成しています。
[list]という名前のリストを作成し、要素は[要素0, 要素1, 要素2]の3つを設定しました。
ループ処理では、「with_random_choice: “{{ list }}”」と記述しています。
これは、前のタスクで作成したリスト[list]を元にしてループを行っています。
with_random_choice では、リストからランダムに要素の1つを選択してループするので、リスト[list]に含まれる要素のどれか1つが使用されてループが行われます。
このプレイブックを2度実行して、実行結果を見てみます。
1回目は、「要素2」が選択されました。
2回目は、「要素1」が選択されました。
1回目の実行と2回目の実行で、使用される要素が変わることが確認出来ました。
実行結果
サンプルのプレイブックを実行した結果になります。
SSH password:
BECOME password[defaults to SSH password]:
PLAY [all] *********************************************************************
TASK [リストの作成] ******************************************************************
ok: [192.168.56.105]
TASK [ループ処理【with_random_choice】] ***********************************************
ok: [192.168.56.105] => (item=要素1) => {
"msg": "要素1"
}
PLAY RECAP *********************************************************************
192.168.56.105 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
「ループ処理の記述方法③」は以上になります。
他のループ処理については、以下の記事をご覧ください。
コメント