Ansible:合并现有变量列表而非覆盖的实现方法
合并Ansible中不同层级的列表变量
要合并group_vars/all.yml和playbook中定义的列表,同时不修改原仓库的group_vars文件,可以通过以下方式实现:
方法1:使用hostvars获取原始列表并拼接
在main.yml的vars中,通过hostvars引用group_vars中定义的原始列表,再与新项拼接:
# main.yml vars: my_list: "{{ hostvars[inventory_hostname].my_list | default([]) }} + ['item 3', 'item 4']"
说明
hostvars[inventory_hostname].my_list:直接获取当前主机在group_vars/all.yml中定义的原始列表,不受play层变量覆盖影响| default([]):避免group_vars中未定义my_list时出现报错,默认使用空列表+:Ansible的列表拼接操作符,将原始列表和新列表合并为一个
执行后,my_list会得到目标结果:['item 1', 'item 2', 'item 3', 'item 4']
方法2:使用set_fact在运行时合并
如果需要更灵活的逻辑,可以在play的pre_tasks中用set_fact完成合并:
# main.yml pre_tasks: - name: 合并my_list set_fact: my_list: "{{ my_list | default([]) }} + ['item 3', 'item 4']" tasks: # 后续任务可直接使用合并后的my_list
说明
pre_tasks会在play的主任务之前执行,此时my_list还是group_vars中的原始值- 合并后的值会覆盖play层变量,后续任务即可使用合并后的列表
你的尝试报错原因
你之前的写法存在两个问题:
my_list: - "{{ my_list }}" - "item 3" - "item 4"
- 将原始
my_list作为单个元素添加到新列表,最终得到嵌套结构[['item 1', 'item 2'], 'item 3', 'item 4'],而非合并后的扁平列表 - 在play的
vars中定义my_list时,直接引用my_list会触发变量递归引用,导致Ansible报错
内容的提问来源于stack exchange,提问作者shepster
相关产品推荐
相关产品推荐

