Ansible: Playbookの実行条件制御 `when` の使い方(2)
前回に引き続き、今回も Playbook でのタスク制御を行なう when
の使い方を勉強していきます。
題材は、引き続き本家のドキュメント。
前回の記事はこちら。
目次
Loops and Conditionals
ループと条件式、ということで、 when
で指定したものでループの制御を行なうところです。
tasks: - command: echo {{ item }} with_items: [ 0, 2, 4, 6, 8, 10 ] when: item > 5
Ansible Playbook では、 with_items
を指定することで command
を繰り返し実行できますが、 when
の指定によって実行するものを調整することができるようです。
実際に実行した結果は、下記のように表示されます。
TASK [command] ***************************************************************** skipping: [server1] => (item=0) skipping: [server1] => (item=2) skipping: [server1] => (item=4) changed: [server1] => (item=6) changed: [server1] => (item=8) changed: [server1] => (item=10)
5未満の数字は skipping
となり、タスク実行がスキップされていることがわかります。
次に、リストと辞書形式リストで繰り返しをするパターンの例が書かれています。
ドキュメントだけだとイマイチ掴めなかったので、実際にリストなどを定義した Playbook を書いて確かめてみました。
- hosts: all vars: mylist: [ 0, 2, 4, 6, 8, 10 ] mydict: a: 0 b: 2 c: 4 d: 6 e: 8 f: 10 tasks: - command: echo {{ item }} with_items: [ 0, 2, 4, 6, 8, 10 ] when: item > 5 - command: echo {{ item }} with_items: "{{ mylist | default([]) }}" when: item > 5 - command: echo {{ item.key }} with_dict: "{{ mydict | default({}) }}" when: item.value > 5
こんな感じです。実行すると、下記のようになります。
TASK [command] ***************************************************************** skipping: [server1] => (item=0) skipping: [server1] => (item=2) skipping: [server1] => (item=4) changed: [server1] => (item=6) changed: [server1] => (item=8) changed: [server1] => (item=10) TASK [command] ***************************************************************** skipping: [server1] => (item=0) skipping: [server1] => (item=2) skipping: [server1] => (item=4) changed: [server1] => (item=6) changed: [server1] => (item=8) changed: [server1] => (item=10) TASK [command] ***************************************************************** skipping: [server1] => (item={'key': u'a', 'value': 0}) skipping: [server1] => (item={'key': u'c', 'value': 4}) skipping: [server1] => (item={'key': u'b', 'value': 2}) changed: [server1] => (item={'key': u'e', 'value': 8}) changed: [server1] => (item={'key': u'd', 'value': 6}) changed: [server1] => (item={'key': u'f', 'value': 10})
mylist
mydict
を実際に定義して動かしてみると、きちんと動きました。
また、 mylist
などの横にある default
ですが、これは Jinja2 の filter 機能で、 “変数が未定義の場合の初期値” として動作するようです。
つまり、 mylist
mydict
が未定義だった場合でも動作するような書き方、ということですね。
Loading in Custom Facts
ここはちょっと(私には)難しいところでした。
書いてある意味は、わかるのですが。。。
tasks: - name: gather site specific fact data action: site_facts - command: /usr/bin/thingy when: my_custom_fact_just_retrieved_from_the_remote_system == '1234'
説明としては、自作のモジュール site_facts
を実行し、その中で定義された facts
である my_custom_fact_just_retrieved_from_the_remote_system
を when
の条件に使えるよ ( Playbook 内の変数だけじゃないよ ) 、、、というものです。
自分で facts
を定義する話については Developing Modules を参照してね、、、とあるので、そのうちモジュール作成についても勉強したいと思います。
Applying ‘when’ to roles and includes
次は、 roles
や include
にも when
が使えるよ、というところです。
これも動きはわかりましたが、説明で一部わからないところが。。。
ドキュメントと順番を変えますが、先に roles
の例から。
- hosts: webservers roles: - { role: debian_stock_config, when: ansible_os_family == 'Debian' }
これはみた通り、 OSが Debian
系ならこのロールが実行される、、、となりそうです。
次は、 include
の例。
- include: tasks/sometasks.yml when: "'reticulating splines' in output"
when
にある英文は、そのまま使えるものじゃありません。
文章的に「ここに色々と条件書けるよ」という風な意味合いですかね。。。
また、ここの説明に「条件はすべてのタスクに適用される」という風に書かれています。
つまり、 include
の条件に適合しなかったタスク(上記だと tasks/sometasks.yml
に記載されているタスクたち)は、すべて評価された上でスキップになる、、、という風な意味合いのようですね。
実際に動かして確認してみます。
試した Playbook は下記。
- hosts: all vars: item: 4 tasks: - include: playbook_task.yml when: - item > 5 - item < 10 - hosts: all vars: item: 6 tasks: - include: playbook_task.yml when: - item > 5 - item < 10
- debug: msg: "Debug:1 {{ item }}" - debug: msg: "Debug:2 {{ item }}"
条件が成立する変数と成立しない変数を用意して、同じタスクを実行するような感じです。
これの実行結果がこちらになります。
PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [server1] TASK [debug] ******************************************************************* skipping: [server1] TASK [debug] ******************************************************************* skipping: [server1] PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [server1] TASK [debug] ******************************************************************* ok: [server1] => { "msg": "Debug:1 6" } TASK [debug] ******************************************************************* ok: [server1] => { "msg": "Debug:2 6" }
前半に skipping
が二つ、後半に ok
が二つ、それぞれありますね。
つまり条件に当てはまらない場合でも、全てのタスクを一度読み込んでスキップ処理を行なう、、、ということですね。
説明に書かれてあったことを、きちんと確認できました。
また、ドキュメントには「group_by
モジュールを使うと、もっと良い感じにできるよ」と書かれているので、こちらも勉強必要ですね。
まとめ
今回は、 when
の使い方の中盤でした。
書かれていることはわかるけど、徐々に複雑なものを取り扱う感じになってきています。
関連して学ぶ必要のあるところも出てきて、まだまだ奥が深いこともわかってきました。
次回で、 when
の使い方を一通り完了したいと思います!