Ansible json_query过滤JSON后复用输出报错、无返回值排查
Ansible json_query 过滤异常排查
问题根因
两个阶段的异常分别对应两个Ansible使用误区:
- 初始未定义变量报错:一是play级变量定义关键字写错,Ansible识别变量定义的关键字是复数
vars,初始代码写的单数var不会生效,会导致后续引用query_general时报未定义;二是直接在变量引用路径里写output.myvar[].display_name属于非法语法,[]数组投影是JMESPath专属语法,原生Jinja2无法解析,会把路径里的片段识别为不存在的变量属性触发报错。 - 修正写法后二次查询返回空值:核心是对
register的返回结构理解错误。register捕获的是Ansible任务的标准返回结构,任务内通过vars定义的临时变量不会直接成为注册变量的顶层属性。你在debug任务里定义的nsx_query_general存放在注册变量output的nsx_query_general字段下,直接对output顶层做[].display_name查询完全匹配不到有效字段,自然返回空值。
正确实现方案
不要用debug模块+register的方式存中间过滤结果,直接用set_fact把每次过滤的结果持久化为自定义事实,逻辑更清晰也不会踩结构错位的坑,参考代码:
tasks: - name: 调用接口获取NSX分段数据 nsxt_rest: hostname: anyhost username: anyuser password: anypass validate_certs: false method: get path: /policy/api/v1/infra/segments register: nsx_results - name: 第一次过滤,提取需要的分段字段 set_fact: filtered_segments: "{{ nsx_results | json_query('body.results[].{display_name: display_name, subnets: subnets[]}') }}" - name: 二次提取所有分段的display_name字段 set_fact: segment_display_names: "{{ filtered_segments | json_query('[].display_name') }}" - name: 输出最终结果 debug: msg: "{{ segment_display_names }}"
避坑说明
- 所有JMESPath语法(包括数组展开
[]、对象投影、管道过滤等)必须包裹在json_query过滤器内部,不能直接写在Jinja2变量引用路径里。 - 不同模块的
register返回结构有固定规范:比如debug模块打印的变量值会存在返回结果的同名键下,不会直接平铺在注册变量顶层,非必要不要用debug模块存中间计算结果。 - play级、任务级变量定义的关键字统一为复数
vars,单数var是无效写法。
内容的提问来源于stack exchange,提问作者Alexander Shelestov
相关产品推荐
相关产品推荐

