如何按双字段唯一过滤字典并实现虚拟机到服务器均匀分配?
Ansible实现虚拟机到服务器的均匀分配(生成对应字典列表)
你需要将虚拟机列表(var1)按顺序循环对应到服务器列表(var2),生成一一匹配的字典列表,而非product过滤器生成的笛卡尔积。以下是两种可行的实现方式:
方法1:通过with_indexed_items任务构建
先定义变量,再通过循环索引取模的方式生成映射列表:
- hosts: localhost vars: var1: ['1','2','3','4','5'] # 虚拟机列表 var2: ['a','b','c'] # 服务器列表 tasks: - name: 生成虚拟机-服务器映射字典列表 set_fact: vm_host_mapping: "{{ vm_host_mapping | default([]) + [{'var1': item.1, 'var2': var2[item.0 % var2|length]}] }}" with_indexed_items: "{{ var1 }}" - name: 验证结果 debug: var: vm_host_mapping
方法2:用Jinja2列表推导式直接定义变量
这种方式更简洁,无需额外任务,直接在变量中生成目标列表:
- hosts: localhost vars: var1: ['1','2','3','4','5'] var2: ['a','b','c'] vm_host_mapping: "{{ [ {'var1': vm, 'var2': var2[idx % var2|length]} for idx, vm in enumerate(var1) ] }}" tasks: - name: 验证结果 debug: var: vm_host_mapping
原理说明
- 利用
enumerate(或with_indexed_items的索引值)获取每个虚拟机的位置索引 - 通过
索引 % 服务器列表长度的取模运算,实现服务器列表的循环复用,确保虚拟机被均匀分配 - 当虚拟机列表和服务器列表长度相等时(如初始示例),取模结果等于索引本身,自然实现一一对应
两种方法都能输出你预期的结果:
初始示例结果:
[{"var1": "1", "var2": "a"}, {"var1": "2", "var2": "b"}, {"var1": "3", "var2": "c"}]
扩展示例结果:
[{"var1": "1", "var2": "a"}, {"var1": "2", "var2": "b"}, {"var1": "3", "var2": "c"}, {"var1": "4", "var2": "a"}, {"var1": "5", "var2": "b"}]
内容的提问来源于stack exchange,提问作者Catwoolfii
相关产品推荐
相关产品推荐

