Ansible如何提取YAML嵌套变量中ifgroups并保留父级tenant与segment名称
实现方案
前置依赖
- 确保Ansible执行节点已安装
jmespath库,json_query过滤器依赖该库,安装命令:pip install jmespath
核心逻辑说明
我们通过JMESPath的父节点引用语法,在遍历最内层ifgroups数组的同时,向上提取所属的segment_name和tenant_name属性,最终拍平为一维数组,完全匹配你需要的变量格式。
完整可运行示例
--- - name: 租户接口组信息提取 hosts: localhost gather_facts: false vars: # 你原有的租户变量 tenants: - tenant_name: ccf_demo description: "ccf demo tenant" state: present segments: - segment_name: segment1 state: present ifgroups: - ifgroup_name: group1 tag: untagged - ifgroup_name: group2 tag: untagged - tenant_name: ccf_demo2 description: "ccf demo2 tenant" state: absent segments: - segment_name: t2seg1 state: present ifgroups: - ifgroup_name: othergroup tag: untagged - tenant_name: ccf_demo3 description: "ccf demo3 tenant" state: present tasks: # 方案1:直接在loop中使用,无需提前定义变量 - name: 直接输出符合要求的信息 debug: msg: "name: {{ item.tenant_name }}_{{ item.segment_name }}_{{ item.ifgroup_name }} is {{ item.ifgroup_name }}:{{ item.tag }}" loop: "{{ tenants | json_query('[].segments[].ifgroups[].{tenant_name: @.^.^.tenant_name, segment_name: @.^.segment_name, ifgroup_name: ifgroup_name, tag: tag}') | list }}" # 方案2:先定义resultVar变量,后续可重复调用 - name: 生成标准化结果变量resultVar set_fact: resultVar: "{{ tenants | json_query('[].segments[].ifgroups[].{tenant_name: @.^.^.tenant_name, segment_name: @.^.segment_name, ifgroup_name: ifgroup_name, tag: tag}') | list }}" - name: 查看resultVar结构 debug: var: resultVar
JMESPath语法说明
[].segments[].ifgroups[]:依次遍历tenants、segments、ifgroups三层数组@:指代当前遍历到的ifgroup对象@.^:指代当前ifgroup所属的上层segment对象,取segment_name属性@.^.^:指代当前segment所属的上层tenant对象,取tenant_name属性- 末尾加
| list是为了确保返回结果为标准列表类型,兼容不同Ansible版本的输出格式
如果你需要过滤仅保留state为present的租户或网段,可在查询条件中增加过滤规则,例如
[?state=='present'].segments[?state=='present'].ifgroups[]即可同时过滤租户和网段的状态。
内容的提问来源于stack exchange,提问作者Dirk Hoffmann
相关产品推荐
相关产品推荐

