Ansible 2.5.1中with_items循环set_fact添加列表元素异常求助
解决Ansible 2.5.1循环中列表仅保留最后一个元素的问题
这个问题我之前也碰到过,Ansible 2.5之后循环里处理列表累加的逻辑确实有调整,咱们一步步拆解原因和解决方案:
问题原因
你原来的代码用了Jinja2的append方法修改局部列表,再通过set_fact赋值,但在Ansible 2.5+中,循环迭代的变量处理逻辑有变化:每次循环的模板渲染时,my_list会使用循环启动前的初始值,而不是上一次set_fact更新后的值。这就导致每次循环都是从[1]开始追加当前item,最后一次迭代的结果会覆盖之前所有的赋值,最终只保留最后一个元素。
解决方案
推荐用列表拼接替代append操作,因为拼接会返回新的列表对象,set_fact能正确更新变量,下一次循环可以获取到最新的列表状态。
简化版实现(推荐)
直接用Ansible的过滤器和列表语法完成累加,代码更简洁:
--- - hosts: - localhost become: false gather_facts: False tasks: - name: Merge firewall variables set_fact: my_list: "{{ my_list | default([1]) + [item] }}" with_items: - a - b - c - debug: msg: "{{ my_list }}"
my_list | default([1]):当my_list未定义时,返回初始列表[1];后续循环会使用上一次set_fact更新后的列表。+ [item]:把当前迭代的item追加到列表末尾,生成新的列表赋值给my_list。
带条件判断的实现(适配复杂场景)
如果需要保留原有的条件判断逻辑,同样用列表拼接替代append:
--- - hosts: - localhost become: false gather_facts: False tasks: - name: Merge firewall variables set_fact: my_list: >- {% if my_list is not defined %} [1, "{{ item }}"] {% else %} {{ my_list + [item] }} {% endif %} with_items: - a - b - c - debug: msg: "{{ my_list }}"
验证结果
运行上述代码后,你会得到期望的输出:
PLAY [localhost] ************************************************************************************************* TASK [Merge firewall variables] ********************************************************************************** ok: [localhost] => (item=a) ok: [localhost] => (item=b) ok: [localhost] => (item=c) TASK [debug] ***************************************************************************************************** ok: [localhost] => { "msg": [ 1, "a", "b", "c" ] } PLAY RECAP ******************************************************************************************************* localhost : ok=2 changed=0 unreachable=0 failed=0
内容的提问来源于stack exchange,提问作者Lollypop
相关产品推荐
相关产品推荐

