Ansible中update_fact结合json_query修改JSON的问题及后续疑问
问题解决指南
1. 修复json_query模板语法错误
你的json_query表达式存在两处语法问题:
- json_query的查询字符串必须用单引号包裹,避免和Ansible模板语法冲突
- 带连字符的字符串值(如
V-256376)需要在查询表达式里用反引号或双引号包裹,否则会被当作变量解析
正确写法示例:
{{ jsondata.stigs[0].rules | json_query('[?group_id==`V-256376`].comments') }}
或用双引号转义:
{{ jsondata.stigs[0].rules | json_query("[?group_id=='V-256376'].comments") }}
2. 批量修改STIG JSON的高效方案
无需拆分JSON结构,通过原生Ansible语法结合循环即可批量更新字段。核心思路是遍历所有rules,匹配API返回结果后动态更新status、comments、finding_details字段。
完整Playbook示例
- name: 读取STIG检查表JSON slurp: src: /path/to/stig_checklist.json register: stig_raw - name: 解析JSON为变量 set_fact: stig_data: "{{ stig_raw.content | b64decode | from_json }}" - name: 调用API获取验证结果(替换为实际uri模块调用) set_fact: api_verify_results: V-256375: status: "not_a_finding" comments: "系统配置符合STIG要求" finding_details: "无异常" V-256376: status: "open" comments: "未启用强制访问控制" finding_details: "/etc/selinux/config中SELINUX状态为disabled" - name: 批量更新rules字段 set_fact: updated_rules: >- {% set temp_list = [] %} {% for rule in stig_data.stigs[0].rules %} {% set verify_res = api_verify_results[rule.group_id] | default({}) %} {% set updated_rule = rule | combine(verify_res) %} {% do temp_list.append(updated_rule) %} {% endfor %} {{ temp_list }} - name: 更新主JSON变量 set_fact: stig_data: "{{ stig_data | combine({'stigs': [{'rules': updated_rules}]}, recursive=True) }}" - name: 将更新后的JSON写入文件 copy: content: "{{ stig_data | to_nice_json(indent=2) }}" dest: /path/to/updated_stig_checklist.json
3. 带连字符键的动态赋值解决方法
Ansible中处理含连字符的键,禁止使用点号引用,必须用方括号语法:
- 静态引用:
api_verify_results['V-256375'](正确),api_verify_results.V-256375(错误,会被解析为变量运算) - 动态引用:若group_id是循环变量(如
item.group_id),直接用api_verify_results[item.group_id]即可,无需额外转义
动态创建带连字符的键示例:
- name: 动态生成带连字符的键值对 set_fact: gid_comments: "{{ gid_comments | default({}) | combine({ item: '自动生成注释' }) }}" loop: - "V-256375" - "V-256376"
内容的提问来源于stack exchange,提问作者Kio
相关产品推荐
相关产品推荐

