如何用Ansible为YAML文件添加address.pincode及删除address.number?
Ansible 修改YAML文件:添加嵌套字段与删除指定键
问题背景
示例YAML文件input.yaml内容如下:
name: "My name" surname: "Bar" address: city: "My city" street: "My street" number: 1
需要实现两个操作:
- 向
address下添加pincode字段并设置值为12345 - 删除
address下的number字段
另外,尝试使用ansible.utils.remove_keys过滤器删除顶层键(如name)有效,但删除嵌套键(如address.city)时失败。
解决方案
一、添加address.pincode字段
通过读取YAML文件转为字典,使用combine过滤器递归合并嵌套字典的方式添加字段,最后写回文件:
# 读取YAML文件内容 - name: 读取input.yaml ansible.builtin.slurp: src: ./input.yaml register: yaml_raw # 将base64编码的内容转为字典 - name: 解析YAML为字典 set_fact: my_data: "{{ yaml_raw.content | b64decode | from_yaml }}" # 嵌套添加pincode字段 - name: 添加address.pincode set_fact: my_data: "{{ my_data | combine({'address': my_data.address | combine({'pincode': 12345})}, recursive=True) }}" # 将修改后的字典写回YAML文件 - name: 保存修改后的内容 ansible.builtin.copy: content: "{{ my_data | to_nice_yaml(indent=2) }}" dest: ./input.yaml
说明:recursive=True参数确保嵌套字典的合并不会覆盖原有address下的其他字段。
二、删除address.number字段
使用ansible.utils.remove_keys过滤器时,需要通过点分隔的路径指定嵌套键,而不是仅写键名:
# 读取并解析YAML文件(步骤同上,可复用) - name: 读取input.yaml ansible.builtin.slurp: src: ./input.yaml register: yaml_raw - name: 解析YAML为字典 set_fact: my_data: "{{ yaml_raw.content | b64decode | from_yaml }}" # 删除嵌套的address.number键 - name: 删除address.number字段 set_fact: my_data: "{{ my_data | ansible.utils.remove_keys(target=['address.number']) }}" # 保存修改后的内容 - name: 保存修改后的内容 ansible.builtin.copy: content: "{{ my_data | to_nice_yaml(indent=2) }}" dest: ./input.yaml
说明:target=['address.number']明确指定了要删除的嵌套键路径,这是之前操作失败的核心原因——仅写键名无法定位到嵌套层级。
如果不想依赖ansible.utils集合,也可以用dict2items+rejectattr的组合实现删除:
- name: 另一种方式删除address.number set_fact: my_data: "{{ my_data | combine({'address': my_data.address | dict2items | rejectattr('key', 'equalto', 'number') | items2dict}) }}"
内容的提问来源于stack exchange,提问作者Arjun
相关产品推荐
相关产品推荐

