Ansible Jinja2模板if判断失效及站点变量合法性校验问题
问题修复方案
1. Jinja2判断永远返回false的原因及修复
错误根因
Jinja2中{% %}是逻辑控制块,内部已经处于变量解析上下文,不需要额外套{{ }}取值符。你原有判断中"{{ item.value.site }}"会被解析为字面量字符串{{ item.value.site }},永远无法匹配newyork/paris,因此永远返回false。
修复后的模板代码(toto/toto.j2)
the {{ item.value.name }} {% if item.value.site in ["newyork", "paris"] %} {{ item.value.site }} = {{ item.value.serie }} {% endif %}
用in判断替代多个or判断,代码更简洁易读。
2. 非法值自动拦截报错的实现
推荐在执行模板渲染任务前新增校验任务,提前拦截异常,避免执行到渲染阶段才发现问题。
修复后的task.yml
# 新增校验任务 - name: 校验site变量合法性 fail: msg: "服务器{{ item.key }}配置异常:{% if item.value.site is undefined %}site变量不存在{% else %}site取值`{{ item.value.site }}`非法,仅允许为newyork/paris{% endif %}" when: item.value.site is undefined or item.value.site not in ["newyork", "paris"] with_dict: "{{ server }}" - name: template file template: src: "toto/toto.j2" dest: "/tmp/toto_{{ item.value.name }}" with_dict: "{{ server }}"
如果需要在模板内直接拦截非法值,可修改模板增加异常分支:
the {{ item.value.name }} {% if item.value.site in ["newyork", "paris"] %} {{ item.value.site }} = {{ item.value.serie }} {% else %} {{ fail("服务器"+item.value.name+"的site取值`"+item.value.site+"`非法,仅允许为newyork/paris") }} {% endif %}
额外注意点
你当前的变量文件中server3的缩进错误,和server平级,不属于server字典的子元素,遍历server时不会读取到server3的配置,需要调整缩进和server1、server2对齐:
server: server1: name: server1 site: newyork serie: "[100,200,300]" server2: name: server2 site: paris serie: "[0,1,2]" server3: name: server3 site: madrid serie: "[0,1,2]"
内容的提问来源于stack exchange,提问作者mariiz443
相关产品推荐
相关产品推荐

