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

## はじめに
タイトルの通り、現状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)](https://github.com/ansible/ansible/issues/13262#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](http://docs.ansible.com/ansible/playbooks_loops.html#loops-and-includes-in-2-0)では
呼出される側（in.yml）でset_factsコマンドでitemを定義していますが、再帰的に変数を利用してまとめて定義したい場合にset_factsでは定義する順番によりエラーとなることがありましたので呼出し側（out.yml）でinclude時に定義した方が変数を扱いやすかったです。
または[公式DOC: loop_control](http://docs.ansible.com/ansible/playbooks_loops.html#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)
```

## 参考
応用例

+ windows MSUファイルによるパッチ当てのサンプル
    + http://qiita.com/tbuchi888/items/c23b856b16aba4ed494f