如何在Ansible中实现三层嵌套字典的嵌套循环?
解决Ansible中嵌套循环匹配字典条目的简化方案
现有Playbook结构
- name: Combine dictionaries based on matching values hosts: localhost gather_facts: false vars: dict1: group1: - "id": 1 "var1": "var1_value" "var2": "var2_value" "var3": "var3_value" - "id": 2 "var1": "var1_value" "var2": "var2_value" "var3": "var3_value" group2: - "id": 3 "var1": "var1_value" "var2": "var2_value" "var3": "var3_value" dict2: "dict2_data": "data": - "var1": "var1_value" "var2": "var2_value" "var3": "var3_value" - "var1": "var1_value" "var2": "var2_value" "var3": "var3_value" tasks:
需求逻辑
需要实现的嵌套循环逻辑(伪代码):
for item0 in dict1: for item1 in item0: for item2 in dict2["dict2_data"]["data"]: if item1["var1"] == item2["var1"] and item1["var3"] == item2["var3"]: print("True")
核心需求:对比dict2.dict2_data.data的每个条目与dict1所有分组下的条目,当var1、var2、var3完全匹配时执行指定操作,且两个字典的条目数量无限制。
现有繁琐方案
目前采用的实现方式复杂度较高:
- 先将条目转换为字典
- 通过嵌套
include_task实现循环,每个循环对应一个独立文件
简化实现方式
不需要拆分任务文件,直接利用Ansible的loop结合过滤器,配合when条件判断即可完成嵌套匹配,以下提供两种简洁方案:
方案一:利用笛卡尔积实现全组合匹配
tasks: - name: 匹配条目并执行操作 debug: msg: "找到匹配条目: group={{ group_name }}, dict1_item={{ dict1_item.id }}, dict2_item={{ dict2_item }}" loop: "{{ dict1 | dict2items | subelements('value') | product(dict2.dict2_data.data) }}" vars: group_name: "{{ item.0.0.key }}" dict1_item: "{{ item.0.1 }}" dict2_item: "{{ item.1 }}" loop_control: label: "{{ group_name }} - {{ dict1_item.id }} 对比 dict2 条目" when: - dict1_item.var1 == dict2_item.var1 - dict1_item.var2 == dict2_item.var2 - dict1_item.var3 == dict2_item.var3
逻辑说明:
dict1 | dict2items:将dict1转换为键值对列表,每个元素为{key: 分组名, value: 分组下的条目列表}subelements('value'):拆分分组下的条目列表,生成(分组信息, 单个条目)的组合product(dict2.dict2_data.data):将上述组合与dict2的data列表做笛卡尔积,生成所有可能的匹配组合when条件:判断三个变量是否完全匹配,匹配时执行任务
方案二:贴近伪代码的分层循环
tasks: - name: 遍历dict1的所有分组 debug: msg: "找到匹配条目: group={{ group_name }}, dict1_item={{ dict1_item.id }}, dict2_item={{ dict2_item }}" loop: "{{ dict2.dict2_data.data }}" vars: group_name: "{{ outer_item.key }}" dict1_item: "{{ outer_item.value }}" dict2_item: "{{ item }}" when: - dict1_item.var1 == dict2_item.var1 - dict1_item.var2 == dict2_item.var2 - dict1_item.var3 == dict2_item.var3 loop_control: label: "{{ group_name }} - {{ dict1_item.id }} 对比 dict2 条目" with_subelements: - "{{ dict1 | dict2items }}" - value
逻辑说明:
with_subelements:先遍历dict1的每个分组,再遍历分组下的每个条目- 内层
loop:遍历dict2的所有数据条目 when条件:完成变量匹配判断后执行任务,逻辑完全贴合你给出的伪代码结构
内容的提问来源于stack exchange,提问作者Oleg Zagrebelsky
相关产品推荐
相关产品推荐

