AnsibleのJinja2を活用してtemplateモジュールの中で配列をループさせる

## やりたい事
　with_dictのような機能を使って、templateの中の構文を配列単位でループさせたい


要は…

```bash:例：haproxy.conf
backend web1_status
        mode tcp
        balance first
        option tcpka
        option httpchk GET /httpchk.php
        server web1 192.168.111.111:80 check port 80 inter 60s rise 1 fall 1
backend web2_status
        mode tcp
        balance roundrobin
        option tcpka
        option httpchk GET /
        server web2 192.168.222.222:80 check port 80 inter 30s rise 3 fall 1
backend web3_status
        mode tcp
        balance static-rr
        option tcpka
        option httpchk GET /index.html
        server web2 192.168.333.333:80 check port 80 inter 10s rise 5 fall 3
```
など、ある程度規則性があるものを変数化させループさせたい。

という感じ。
※設定内容はあくまで例となります。

そもそもwith_dictはansibleのモジュールの処理内でループさせるものでtemplateモジュール内の特定の1ファイル内に対してはループができなさそう。(個人的見解です)

似たようなものでuseraddモジュールをwith_dictを使ってループさせたりはしていたのだがそれとも違う。

```yaml:tasks/useradd.yml
---
- name: ユーザ作成
  user:
    name: "{{ item.key }}"
    uid: "{{ item.value.uid }}"
    group: "{{ item.value.group }}"
    groups: "{{ item.value.groups }}"
    password: "{{ item.value.password }}"
    shell: "{{ item.value.shell}}"
    home: "{{ item.value.home}}"
  with_dict: "{{ users }}"
  no_log: true
```

```yaml:vars/useradd.yml
users:
  aaa:
      uid: 1
      password: *****
      group: aaa
      groups:
      shell: "/bin/bash"
      home: "/home/aaa"
  bbb:
      uid: 222
      password: *****
      group: bbb
      groups: wheel
      shell: "/bin/bash"
      home: "/home/bbb"
```

また、1項目のみの変数化でいいのであれば以下のような感じでできるけどそれも違う。

```jinja:templates/nginx.conf
{% if server=='aaa' %}
{% for web_ip in nginx.web_ips %}
	server {{ web_ip }}:80 max_fails=2 fail_timeout=300s;
{% endfor %}
```
```yaml:vars/vars.yml
nginx:
  web_ips:
    - 192.168.111.111
    - 192.168.222.222
```

という事で1日中試行錯誤した結果できたのが以下。

## 結果

```yaml:tasks/main.yml
- name: 設定ファイル設置
  template: src=haproxy.conf dest=/etc/haproxy/haproxy.conf owner=root group=root mode=0644
```
```jinja:templates/haproxy.conf
{% if inventory_directory=='haproxy' %}
{% for item in web_services %}
backend {{ web_services[item].name }}_status
        mode tcp
        balance {{ web_services[item].balance }}
        option tcpka
        option httpchk GET {{ web_services[item].url }}
        server {{ web_services[item].name }} {{ web_services[item].ip }}:80 check port 80 inter {{ web_services[item].inter }} rise {{ web_services[item].rise }} fall {{ web_services[item].fall }}
{% endfor %}
{% endif %}
```

```yaml:vars/vars.yml
web_services:
  web1:
    name: web1
    balance: first
    url: /httpchk.php
    ip: 192.168.111.111
    inter: 60s
    rise: 1
    fall: 1
  web2:
    name: web2
    balance: roundrobin
    url: /
    ip: 192.168.222.222
    inter: 30s
    rise: 3
    fall: 1
  web3:
    name: web3
    balance: static-rr
    url: /index.html
    ip: 192.168.333.333
    inter: 10s
    rise: 5
    fall: 3

```

※参考にしたのはこれ
[jinja2 - Loop dictionary in ansible template - Stack Overflow](https://stackoverflow.com/questions/37756586/loop-dictionary-in-ansible-template)

上の記事も今回やりたいことと目的が違ったが配列をtempalteに落とし込む際には使えそうだったので参考にさせて頂きました。


とりあえず久しぶりにansibleと格闘して途中諦めかけたがなんとかできてよかった…。

もっと他に効率のいい方法などあれば教えて下さい。

## 課題

課題としてはfor文での出力がトップダウン方式ではなくでランダムになってしまう場合がある。(ある程度規則性はあるのだろうが不明)

varsには

```
web1:
web2:
web3:
```

で書いたのに
出力が

```
web3:
web1:
web2:
```

のようになってしまう。※実際の文字列はもう少し不規則なもの
現状問題はないができれば順番に出したい。
というか前にもおんなじことではまってた気がする。

一旦`web1:`の部分を`1:`のように数字順にする事で解決できたが、何かいい解決策はないだろうか…。