如何用Ansible向YAML文件的字典列表中添加新条目?
解决Ansible向YAML文件的sites列表追加条目而非覆盖的问题
你的问题出在使用combine过滤器的默认行为上:combine会直接替换字典中同名键的内容,而不是合并列表,所以原有sites列表被新的单条目列表覆盖了。
要实现**追加条目(或不存在时创建)**的需求,需要先取出原有sites列表(如果不存在则用空列表),把新条目追加到列表末尾,再将合并后的列表赋值回sites键。
修改后的完整Playbook
tasks: - name: 定义要追加的新站点条目 ansible.builtin.set_fact: new_item: sites: - name: site 3 site: www.site3.com delegate_to: localhost - name: 读取现有YAML文件内容 ansible.builtin.set_fact: current_file: "{{ lookup('file', inventory_dir +'/group_vars/all/site_vars.yaml') | from_yaml }}" - name: 追加新条目到sites列表(不存在则创建) set_fact: current_file: "{{ current_file | combine({'sites': (current_file.sites | default([])) + new_item.sites}) }}" - name: 写入更新后的内容到新文件 copy: dest: "{{ inventory_dir +'/group_vars/all/vars_new.yaml' }}" content: "{{ current_file | to_nice_yaml }}" delegate_to: localhost
关键逻辑说明
current_file.sites | default([]):如果原文件中没有sites键,就用空列表替代,避免报错(...) + new_item.sites:将原有列表(或空列表)和新条目列表相加,实现追加效果combine({'sites': ...}):把合并后的列表重新赋值给sites键,同时保留文件中其他原有键(比如test)
运行后预期结果
生成的vars_new.yaml内容会是:
test: hello sites: - name: site 1 site: www.site1.com - name: site 2 site: www.site2.com - name: site 3 site: www.site3.com
内容的提问来源于stack exchange,提问作者Ian Gregson
相关产品推荐
相关产品推荐

