Ansible/Jinja:按VCENTERNAME匹配合并两个字典列表键值
Ansible字典列表匹配合并解决方案
环境说明
- ansible-core 2.15.11
- 依赖集合:community.general、posix
- 运行环境:RHEL 7、Python 3.9.19
需求描述
现有两个字典列表vcenterinfo和provdata,当两者的VCENTERNAME字段匹配时,将vcenterinfo中的AZ、POD键值对合并到provdata的对应字典中。
示例数据
vcenterinfo
vcenterinfo: - VCENTERNAME: "vc01" AZ: ["az1", "az2"] POD: ["pod1", "pod2"] unused_key: "无需合并" - VCENTERNAME: "vc02" AZ: ["az3"] POD: ["pod3"]
provdata
provdata: - NAME: "vm1" VCENTERNAME: "vc01" spec: "small" - NAME: "vm2" VCENTERNAME: "vc02" spec: "large" - NAME: "vm3" VCENTERNAME: "vc03" spec: "medium"
期望结果
updated_provdata: - NAME: "vm1" VCENTERNAME: "vc01" spec: "small" AZ: ["az1", "az2"] POD: ["pod1", "pod2"] - NAME: "vm2" VCENTERNAME: "vc02" spec: "large" AZ: ["az3"] POD: ["pod3"] - NAME: "vm3" VCENTERNAME: "vc03" spec: "medium"
可行解决方案
使用Ansible的selectattr、combine等过滤器实现精准匹配与字段合并:
- name: 初始化合并结果列表 set_fact: updated_provdata: [] - name: 匹配VCENTERNAME并合并AZ、POD字段 set_fact: updated_provdata: "{{ updated_provdata + [item | combine(vcenter_match)] }}" loop: "{{ provdata }}" vars: # 筛选匹配的vcenterinfo条目,仅保留AZ、POD字段 vcenter_match: >- {{ vcenterinfo | selectattr('VCENTERNAME', 'equalto', item.VCENTERNAME) | first | default({}, true) | dict(include_keys=['AZ', 'POD']) }} - name: 输出合并结果 debug: var: updated_provdata
常见失败原因分析
- 语法错误:大概率是过滤器参数使用错误(比如
items2dict的key_name/value_name参数写错),或者combine的嵌套逻辑不符合Ansible语法规范。 - 空AZ列表:可能是匹配逻辑未正确命中条目(比如
selectattr的条件拼写错误),或者未使用default({}, true)处理无匹配的情况,导致合并了空值字段;也可能是未通过dict(include_keys)过滤字段,导致原字段不存在时返回默认空列表。
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

