LoginSignup
9
9

More than 5 years have passed since last update.

Ansible block単位でLoopしたい!でも、出来ない ので ワークアラウンド

Last updated at Posted at 2016-07-08

はじめに

タイトルの通り、現状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)

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)

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)

参考

応用例

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9