You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible遍历嵌套字典保留各级键名的实现方法

实现方法

不需要修改原始数据结构,也不需要单独创建任务文件实现嵌套循环,以下两种原生Ansible写法可直接满足需求:

方法1:过滤器组合实现单层循环(最简洁)

通过dict2items+subelements过滤器一次性将两层嵌套字典打平为单循环列表,完全匹配你的使用预期:

- name: 处理所有分组下的虚拟机
  ansible.builtin.debug: # 替换为你的实际任务模块
    msg:
      vms: "{{ item.1.value }}"
      group: "{{ item.1.key }}"
      cluster: "{{ item.0.key }}"
  loop: "{{ all_vms | dict2items | subelements('value | dict2items') }}"

循环中每个item是包含两个元素的元组:

  • item.0对应第一层集群的键值对,item.0.key为集群名
  • item.1对应当前集群下分组的键值对,item.1.key为分组名,item.1.value为该分组下的虚拟机列表

如果觉得item.0/item.1可读性差,可以通过临时变量优化写法:

- name: 处理所有分组下的虚拟机
  ansible.builtin.debug:
    msg:
      vms: "{{ group_item.value }}"
      group: "{{ group_item.key }}"
      cluster: "{{ cluster_item.key }}"
  loop: "{{ all_vms | dict2items | subelements('value | dict2items') }}"
  loop_control:
    loop_var: __tmp
  vars:
    cluster_item: "{{ __tmp.0 }}"
    group_item: "{{ __tmp.1 }}"

方法2:Jinja2原生组装扁平列表(无额外过滤器依赖)

如果不想依赖subelements过滤器,可以直接通过Jinja2语法在循环定义处遍历两层结构,组装成所需的扁平列表,不需要修改原始数据:

- name: 处理所有分组下的虚拟机
  ansible.builtin.debug:
    msg:
      vms: "{{ entry.vms }}"
      group: "{{ entry.group }}"
      cluster: "{{ entry.cluster }}"
  loop: >-
    {%- set flat_list = [] -%}
    {%- for cluster_name, groups in all_vms.items() -%}
    {%- for group_name, vm_list in groups.items() -%}
    {%- set _ = flat_list.append({
        'cluster': cluster_name,
        'group': group_name,
        'vms': vm_list
      }) -%}
    {%- endfor -%}
    {%- endfor -%}
    {{ flat_list }}

补充说明

你之前尝试的block嵌套循环写法不生效,是因为Ansible的block级循环不会自动将外层循环变量透传给块内任务,这也是为什么嵌套循环通常需要配合include_tasks拆分任务文件。上述两种方法都绕开了这个限制,直接通过单层循环拿到所有层级的键名,没有冗余代码。

你之前提到的json_query方案也可以实现,只需调整JMESPath表达式即可,但可读性远低于上述原生写法,不推荐使用。


内容的提问来源于stack exchange,提问作者wfaulk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:33:17