如何在Ansible中使用过滤器将字典列表转换为按groupid分组的列表字典?
Ansible:按groupid分组转换字典列表为目标字典结构
没问题,我来帮你搞定这个Ansible过滤器的转换需求!你需要把一个包含主机信息的字典列表,按groupid分组,转换成以groupid为键、对应主机详情列表为值的结构,同时还要调整部分字段名(比如把hostname改成host)。这用Ansible的内置过滤器和Jinja2循环就能轻松实现,我给你一步步拆解:
核心思路
- 用
groupby过滤器按groupid对原始列表分组,得到(groupid, 对应主机字典列表)的元组集合。 - 对每个分组里的主机字典,移除不需要的
groupid字段,同时把hostname替换成host。 - 将处理后的分组结果合并成最终的字典结构。
完整实现示例
下面是一个可直接运行的Playbook,包含变量定义和转换逻辑:
- name: 转换字典列表为按groupid分组的字典 hosts: localhost vars: # 你的原始输入数据 _list_of_dict: - groupid: "11" hostname: "host1.local" timeout: "5000" status: "ONLINE" - groupid: "12" hostname: "host1.local" timeout: "5000" status: "ONLINE" - groupid: "12" hostname: "host2.local" timeout: "5000" status: "ONLINE" tasks: - name: 生成目标结构的字典 set_fact: _dict_of_list: >- {% set grouped_hosts = _list_of_dict | groupby('groupid') %} {% set final_dict = {} %} {% for group_id, host_items in grouped_hosts %} {% set processed_hosts = host_items | map('combine', {'host': item.hostname}, omit('groupid', 'hostname')) | list %} {% set final_dict = final_dict | combine({group_id: processed_hosts}) %} {% endfor %} {{ final_dict }} - name: 打印转换后的结果 debug: var: _dict_of_list
代码解释
groupby('groupid'):把原始列表按groupid字段分组,输出是一个元组列表,每个元组的第一个元素是groupid值,第二个元素是对应组下的所有主机字典。map('combine', {'host': item.hostname}, omit('groupid', 'hostname')):对每个主机字典,用combine添加新的host字段(值来自原hostname),同时用omit参数移除groupid和hostname这两个不需要的字段。combine({group_id: processed_hosts}):把每个分组的处理结果合并到最终字典中,确保每个groupid对应正确的主机列表。
最终输出
运行上面的Playbook后,你会得到完全符合预期的结果:
_dict_of_list: "11": - host: "host1.local" timeout: "5000" status: "ONLINE" "12": - host: "host1.local" timeout: "5000" status: "ONLINE" - host: "host2.local" timeout: "5000" status: "ONLINE"
这个方案完全支持任意数量的groupid和每个组任意数量的主机,不管输入数据怎么变化,都能正确完成分组转换。
内容的提问来源于stack exchange,提问作者Artemii Emelianov
相关产品推荐
相关产品推荐

