やりたい事
with_dictのような機能を使って、templateの中の構文を配列単位でループさせたい
要は…
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を使ってループさせたりはしていたのだがそれとも違う。
---
- 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
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項目のみの変数化でいいのであれば以下のような感じでできるけどそれも違う。
{% if server=='aaa' %}
{% for web_ip in nginx.web_ips %}
server {{ web_ip }}:80 max_fails=2 fail_timeout=300s;
{% endfor %}
nginx:
web_ips:
- 192.168.111.111
- 192.168.222.222
という事で1日中試行錯誤した結果できたのが以下。
結果
- name: 設定ファイル設置
template: src=haproxy.conf dest=/etc/haproxy/haproxy.conf owner=root group=root mode=0644
{% 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 %}
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
上の記事も今回やりたいことと目的が違ったが配列をtempalteに落とし込む際には使えそうだったので参考にさせて頂きました。
とりあえず久しぶりにansibleと格闘して途中諦めかけたがなんとかできてよかった…。
もっと他に効率のいい方法などあれば教えて下さい。
課題
課題としてはfor文での出力がトップダウン方式ではなくでランダムになってしまう場合がある。(ある程度規則性はあるのだろうが不明)
varsには
web1:
web2:
web3:
で書いたのに
出力が
web3:
web1:
web2:
のようになってしまう。※実際の文字列はもう少し不規則なもの
現状問題はないができれば順番に出したい。
というか前にもおんなじことではまってた気がする。
一旦web1:
の部分を1:
のように数字順にする事で解決できたが、何かいい解決策はないだろうか…。