はじめに
タイトルの通り、現状Ansible Ver.2.2.0(devel 394430a61e last updated 2016/06/28)でも、blockに対してwith_*でのループ処理はできません。
今年(2016年)6月にAnsibleのPrincipal Product ManagerのDylan Silva氏が
来日した際にWorkshopで質問しましたができないとのことでした。
コミュニティ次第のようなことを言っていたと思います。
なお、こちら(issue-118433547)の通り要望はあがっていますが。。。
ワークアラウンド
どうしてもblock単位でループ処理をしたい時のワークアラウンドは(issue-118433547にも書いてあるように)
include
を利用してblock
を含むtask
のプレイブック自体をwith_*
でループさせます。
ただし、本ワークアラウンドはAnsible ver2.0以降での対応となります。
使用例
- 呼出し側(out.yml)と呼出される側(in.yml)の2つのplyaybookを用意します。
- 呼出し側(out.yml)
- lsコマンドの結果をwith_itemsの変数として利用します。
- blockを含む呼出される側(in.yml)をincludeし、さらにwith_itemsでループ処理します。
- 呼出される側(in.yml)
- block/rescue/alwaysにそれぞれdebugモジュールでメッセージを表示します。
なお、公式DOC: loops-and-includes-in-2-0では
呼出される側(in.yml)でset_factsコマンドでitemを定義していますが、再帰的に変数を利用してまとめて定義したい場合にset_factsでは定義する順番によりエラーとなることがありましたので呼出し側(out.yml)でinclude時に定義した方が変数を扱いやすかったです。
または公式DOC: loop_controlの通りloop_control: loop_var:
を利用するなど
サンプルplaybook
呼出し側(out.yml)
---
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: "Get files name"
shell: ls
delegate_to: localhost
register: command_result
- name: "include in.yml"
include: in.yml in_item={{ item }}
with_items: "{{ command_result.stdout_lines }}"
呼出される側(in.yml)
---
- block:
- debug: msg="Block START ----------------------"
- debug: msg="debug 1 in_item is \"{{ in_item }} \""
- debug: msg="debug 2 in_item is \"{{ in_item }} \""
- debug: msg="Block END ------------------------"
rescue:
- debug: msg="Rescue START ---------------------"
- debug: msg="debug 3 in_item is \"{{ in_item }} \""
- debug: msg="Rescue END -----------------------"
always:
- debug: msg="Always START ---------------------"
- debug: msg="debug 4 in_item is \"{{ in_item }} \""
- debug: msg="Always END -----------------------"
カレントディレクトリの状態(ls結果)
# ls
in.yml out.yml
playbook実行結果
# ansible-playbook out.yml
PLAY [localhost] ***************************************************************
TASK [Get files name] **********************************************************
changed: [localhost -> localhost]
TASK [include in.yml] **********************************************************
included: /opt/q/in.yml for localhost
included: /opt/q/in.yml for localhost
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Block START ----------------------"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "debug 1 in_item is \"in.yml \""
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "debug 2 in_item is \"in.yml \""
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Block END ------------------------"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Always START ---------------------"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "debug 4 in_item is \"in.yml \""
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Always END -----------------------"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Block START ----------------------"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "debug 1 in_item is \"out.yml \""
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "debug 2 in_item is \"out.yml \""
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Block END ------------------------"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Always START ---------------------"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "debug 4 in_item is \"out.yml \""
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Always END -----------------------"
}
PLAY RECAP *********************************************************************
localhost : ok=17 changed=1 unreachable=0 failed=0
#
実行環境
Ansible Server実行環境
# ansible --version
ansible 2.2.0 (devel 394430a61e) last updated 2016/06/28 13:25:07 (GMT +900)
lib/ansible/modules/core: (detached HEAD 3c6f2c2db1) last updated 2016/06/28 13:25:30 (GMT +900)
lib/ansible/modules/extras: (detached HEAD 1c36665545) last updated 2016/06/28 13:25:37 (GMT +900)
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
# cat /etc/redhat-release
CentOS release 6.7 (Final)
参考
応用例
- windows MSUファイルによるパッチ当てのサンプル