Ansible: Playbookの繰り返し制御の色々 (1)
以前のシリーズで、 when
を中心とした実行時の条件制御について見てきました。 今回からは、 Loops
のドキュメントを参考に、繰り返し制御について学んでいきたいと思います。
こちらも、題材は本家のドキュメント。
Ansible Documentation > Playbooks > Loops
シリーズはこちら。
https://blog.tacck.net/ansible-documents-translate/ansible-loops
Standard Loops
まずは、標準的なループの指定です。 ここでは、 with_items
の使い方を見ていきます。
サンプルでは、「単純な指定」、「変数の配列による指定」「ハッシュ形式の配列による指定」とあるので、それらを確認できる Playbook を準備します。
- hosts: 127.0.0.1
connection: local
vars:
somelist:
- var_item1
- var_item2
tasks:
- name: debug with "with_items"
debug:
msg: "{{ item }}"
with_items:
- item1
- item2
- name: debug with "vars"
debug:
msg: "{{ item }}"
with_items: "{{ somelist }}"
- name: debug with hash items
debug:
msg: "{{ item.name }}, {{ item.value }}"
with_items:
- { name: "item1", value: "foo" }
- { name: "item2", value: "bar" }
こちらを実行すると、下記のようにそれぞれきちんと動いていることが確認できます。
PLAY [127.0.0.1] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [debug with "with_items"] *************************************************
ok: [localhost] => (item=item1) => {
"item": "item1",
"msg": "item1"
}
ok: [localhost] => (item=item2) => {
"item": "item2",
"msg": "item2"
}
TASK [debug with "vars"] *******************************************************
ok: [localhost] => (item=var_item1) => {
"item": "var_item1",
"msg": "var_item1"
}
ok: [localhost] => (item=var_item2) => {
"item": "var_item2",
"msg": "var_item2"
}
TASK [debug with hash items] ***************************************************
ok: [localhost] => (item={u'name': u'item1', u'value': u'foo'}) => {
"item": {
"name": "item1",
"value": "foo"
},
"msg": "item1, foo"
}
ok: [localhost] => (item={u'name': u'item2', u'value': u'bar'}) => {
"item": {
"name": "item2",
"value": "bar"
},
"msg": "item2, bar"
}
PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0
ここでサラッと書かれているのですが、 with_ + lookup()
という形式で上記のようなループ処理を行なうことができます。 つまり、 <a rel="nofollow" href="http://docs.ansible.com/ansible/playbooks_lookups.html" target="_blank">Lookupプラグイン</a>
をそのまま使える、ということのようです。 こちらの詳細は、別の機会に調べたいと思います。
Nested Loops
Loopの条件をネスト(入れ子)にできるようです。 つまり、複数の配列に対して全組み合わせの繰り返しができる、という感じですね。 こちらは with_nested
を利用します。
本文の例を基に、実際に Playbook を作成して動作を確認してみましょう。
- hosts: 127.0.0.1
connection: local
vars:
users:
- user_a
- user_b
tasks:
- name: show users and commands
debug:
msg: "{{ item[0] }}, {{ item[1] }}"
with_nested:
- [ "user_1", "user_2" ]
- [ "command_a", "command_b", "command_c" ]
- name: show users and commands with vars
debug:
msg: "{{ item[0] }}, {{ item[1] }}"
with_nested:
- "{{ users }}"
- [ "command_a", "command_b", "command_c" ]
実行すると、下記のようになります。
PLAY [127.0.0.1] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [show users and commands] *************************************************
ok: [localhost] => (item=[u'user_1', u'command_a']) => {
"item": [
"user_1",
"command_a"
],
"msg": "user_1, command_a"
}
ok: [localhost] => (item=[u'user_1', u'command_b']) => {
"item": [
"user_1",
"command_b"
],
"msg": "user_1, command_b"
}
ok: [localhost] => (item=[u'user_1', u'command_c']) => {
"item": [
"user_1",
"command_c"
],
"msg": "user_1, command_c"
}
ok: [localhost] => (item=[u'user_2', u'command_a']) => {
"item": [
"user_2",
"command_a"
],
"msg": "user_2, command_a"
}
ok: [localhost] => (item=[u'user_2', u'command_b']) => {
"item": [
"user_2",
"command_b"
],
"msg": "user_2, command_b"
}
ok: [localhost] => (item=[u'user_2', u'command_c']) => {
"item": [
"user_2",
"command_c"
],
"msg": "user_2, command_c"
}
TASK [show users and commands with vars] ***************************************
ok: [localhost] => (item=[u'user_a', u'command_a']) => {
"item": [
"user_a",
"command_a"
],
"msg": "user_a, command_a"
}
ok: [localhost] => (item=[u'user_a', u'command_b']) => {
"item": [
"user_a",
"command_b"
],
"msg": "user_a, command_b"
}
ok: [localhost] => (item=[u'user_a', u'command_c']) => {
"item": [
"user_a",
"command_c"
],
"msg": "user_a, command_c"
}
ok: [localhost] => (item=[u'user_b', u'command_a']) => {
"item": [
"user_b",
"command_a"
],
"msg": "user_b, command_a"
}
ok: [localhost] => (item=[u'user_b', u'command_b']) => {
"item": [
"user_b",
"command_b"
],
"msg": "user_b, command_b"
}
ok: [localhost] => (item=[u'user_b', u'command_c']) => {
"item": [
"user_b",
"command_c"
],
"msg": "user_b, command_c"
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
上記のように、それぞれ6通りずつ実行されました。
Looping over Hashes
ここでは、ハッシュ形式を使ったループの例となっています。 最初に「ハッシュ形式の配列による指定」がありましたが、全体がハッシュ形式となった変数での例です。 利用するのは with_dict
となります。
- hosts: 127.0.0.1
connection: local
vars:
users:
alice:
name: Alice Appleworth
telephone: 123-456-7890
bob:
name: Bob Bananarama
telephone: 987-654-3210
tasks:
- name: Print phone records
debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
with_dict: "{{ users }}"
実行してみると、下記のようになります。
PLAY [127.0.0.1] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [Print phone records] *****************************************************
ok: [localhost] => (item={'key': u'bob', 'value': {u'name': u'Bob Bananarama', u'telephone': u'987-654-3210'}}) => {
"item": {
"key": "bob",
"value": {
"name": "Bob Bananarama",
"telephone": "987-654-3210"
}
},
"msg": "User bob is Bob Bananarama (987-654-3210)"
}
ok: [localhost] => (item={'key': u'alice', 'value': {u'name': u'Alice Appleworth', u'telephone': u'123-456-7890'}}) => {
"item": {
"key": "alice",
"value": {
"name": "Alice Appleworth",
"telephone": "123-456-7890"
}
},
"msg": "User alice is Alice Appleworth (123-456-7890)"
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
このように、ハッシュ形式のデータを直接利用することができました。
まとめ
今回はループを行なうものとして、 with_items
、 with_nested
、 with_dict
の例を見てきました。 今回の範囲は比較的シンプルで、プログラミング経験があればかなり直感的に理解できるところだと思います。
原文のこの章はまだまだ先が長いので、じっくりと確認しながら学んで行きたいと思います。