Template 裡 for 回圈內的變數處理
ansible template 模組的範本可以使用 jinja2 語法,在一般應用上足敷使用,真的要當程式來寫,for 回圈要配置變數時,就會遇到問題了。
來看看這情境
{% set data = hostvars | dict2items | rejectattr('key', 'equalto', 'localhost') | items2dict %}
{% set data_list = [] %}
{% for _hostname, _hostvar in data.items() %}
{% set data_list = data_list + [{'key': _hostname, 'value': {'check_result': 'check_result' | extract(_hostvar) }}] %}
{% endfor %}
{% set final_data = data_list | items2dict %}
預期 data_list 會有結果,但最終結果會發現 data_list 仍然是空的。
我沒有去翻閱 jinja2 的實作,但我猜測,應該是變數的設置只限於回圈裏面。
找了好幾篇文章,終於找到可以解決的方式:
但要先說這不是官方解法,未來有可能會失效。
解法是利用 namespace object,一樣用上面當例子,改寫如下
{% set data = hostvars | dict2items | rejectattr('key', 'equalto', 'localhost') | items2dict %}
{% set ns = namespace(data_list = []) %}
{% for _hostname, _hostvar in data.items() %}
{% set ns.data_list = ns.data_list + [{'key': _hostname, 'value': {'check_result': 'check_result' | extract(_hostvar) }}] %}
{% endfor %}
{% set final_data = ns.data_list | items2dict %}
利用 namespace object 的寫法,就可以有符合預期的結果了。