Ansible Playbook中json_query无法正确筛选旧数据,请求排查
Ansible Playbook 错误排查与修正
核心错误点
- Debug模块参数错误:第三个debug任务使用了
job:作为输出参数,但debug模块的正确输出参数是msg:,这会导致任务执行异常,无法正确注册变量。 - JSON Query语法完全错误:你写的
json_query('environments[*]',<3 months)不符合JMESPath语法规范,JMESPath需要完整的表达式来实现筛选逻辑,且日期比较必须嵌入表达式内。 - 嵌套结构未正确展开:API返回的是多层嵌套的列表(results → environments),直接用
environments[*]无法遍历所有results项里的environments。
修正后的Playbook(两种实现方式)
方式一:使用Ansible原生过滤器(更直观)
vars: begin_date: "{{ lookup('pipe', 'date -d \"3 months ago\" -I') }}" # 输出格式YYYY-MM-DD tasks: - debug: msg: "{{ begin_date }}" - name: Get all data from API uri: url: "127.0.0.1/api" user: "{{ user }}" password: "{{ pass }}" method: GET force_basic_auth: yes status_code: 200 validate_certs: no register: data ignore_errors: yes - name: Filter environments older than 3 months set_fact: old_envs: "{{ data.json.results | subelements('environments') | map(attribute='1') | selectattr('publish_date', '<', begin_date) | map(attribute='name') | list }}" - debug: msg: "Environments older than 3 months: {{ old_envs }}"
逻辑说明:
subelements('environments'):将results列表中每个项的environments嵌套列表扁平化,返回[result项, environment项]的元组map(attribute='1'):提取元组中的environment项selectattr('publish_date', '<', begin_date):筛选发布日期早于3个月前的项map(attribute='name'):提取符合条件的环境名称,最终组成列表
方式二:使用JSON Query(JMESPath语法)
vars: begin_date: "{{ lookup('pipe', 'date -d \"3 months ago\" -I') }}" tasks: - debug: msg: "{{ begin_date }}" - name: Get all data from API uri: url: "127.0.0.1/api" user: "{{ user }}" password: "{{ pass }}" method: GET force_basic_auth: yes status_code: 200 validate_certs: no register: data ignore_errors: yes - name: Filter with json_query set_fact: old_envs: "{{ data.json.results | json_query('[*].environments[?publish_date < `' ~ begin_date ~ '`].name') | flatten }}" - debug: msg: "Environments older than 3 months: {{ old_envs }}"
逻辑说明:
[*].environments:遍历所有results项,展开其下的environments列表[?publish_date <' ~ begin_date ~ ']:筛选发布日期早于指定日期的环境项.name:提取符合条件的环境名称flatten:将多层嵌套的名称列表转为一维列表
额外注意事项
确保API返回的publish_date格式为YYYY-MM-DD(与begin_date一致),否则字符串比较会失效。如果publish_date是带时分秒的格式(如YYYY-MM-DD HH:MM:SS),需改用日期对象比较:
old_envs: "{{ data.json.results | subelements('environments') | map(attribute='1') | selectattr('publish_date', 'lt', begin_date | to_datetime) | map(attribute='name') | list }}"
内容的提问来源于stack exchange,提问作者talion.kel
相关产品推荐
相关产品推荐

