Ansible技术问题:如何仅当所有循环found值>0时标记合规
问题:Ansible规则结果判断不符合预期
需求说明
- 已通过命令调试输出检查文件中的特定行
- 需确保所有推荐行都存在于
/tmp/test.txt文件中,只要有一行不存在,结果就不能设置为COMPLIANT - 当前代码输出结果为
COMPLIANT,但调试输出中存在item.found=0的情况(对应行black xzy不存在),预期结果应为非合规
调试输出
ok: [localhost] => { "output": { "changed": false, "msg": "All items completed", "results": [ { "ansible_loop_var": "item", "backup": "", "changed": false, "failed": false, "failed_when_result": false, "found": 1, "invocation": { "module_args": { "attributes": null, "backrefs": false, "backup": false, "create": false, "dest": "/tmp/test.txt", "firstmatch": false, "group": null } }, "item": "black abc", "msg": "1 line(s) removed" }, { "ansible_loop_var": "item", "backup": "", "changed": false, "failed": false, "failed_when_result": false, "found": 1, "invocation": { "module_args": { "attributes": null, "backrefs": false, "backup": false, "create": false, "dest": "/tmp/test.txt", "firstmatch": false, "group": null } }, "item": "inst abc", "msg": "1 line(s) removed" }, { "ansible_loop_var": "item", "backup": "", "changed": false, "failed": false, "failed_when_result": false, "found": 1, "invocation": { "module_args": { "attributes": null, "backrefs": false, "backup": false, "create": false, "dest": "/tmp/test.txt", "firstmatch": false, "group": null } }, "item": "black efd", "msg": "1 line(s) removed" }, { "ansible_loop_var": "item", "backup": "", "changed": false, "failed": false, "failed_when_result": false, "found": 1, "invocation": { "module_args": { "attributes": null, "backrefs": false, "backup": false, "create": false, "dest": "/tmp/test.txt", "firstmatch": false, "group": null } }, "item": "inst abc", "msg": "1 line(s) removed" }, { "ansible_loop_var": "item", "backup": "", "changed": false, "failed": false, "failed_when_result": false, "found": 0, "invocation": { "module_args": { "attributes": null, "backrefs": false, "backup": false, "create": false, "dest": "/tmp/test.txt", "firstmatch": false, "group": null }, "item": "black xzy", "msg": "" } ], "skipped": false } }
当前使用的Playbook
- name: check config ansible.builtin.lineinfile: line: "{{ item }}" dest: /tmp/test.txt state: absent loop: - "black abc" - "inst abc" - "black efd" - "inst abc" - "black xzy" when: st.stat.exists == true register: output changed_when: false check_mode: yes failed_when: false - name: "Set the result and output when compliant." ansible.builtin.set_fact: rule_result: "COMPLIANT" rule_output: "Recommended setting is configured" when: item.found > 0 loop: "{{ output.results }}" loop_control: label: "{{ item.found }}"
问题原因及解决方案
问题原因
原Playbook的set_fact任务采用循环判断逻辑,只要有任意一个item.found>0就会覆盖设置rule_result=COMPLIANT,完全忽略了存在found=0的缺失行情况,导致结果判断错误。
修正后的Playbook
- name: check config ansible.builtin.lineinfile: line: "{{ item }}" dest: /tmp/test.txt state: absent loop: - "black abc" - "inst abc" - "black efd" - "inst abc" - "black xzy" when: st.stat.exists == true register: output changed_when: false check_mode: yes failed_when: false - name: Set result to COMPLIANT if all lines exist ansible.builtin.set_fact: rule_result: "COMPLIANT" rule_output: "Recommended setting is configured" when: output.results | selectattr('found', 'equalto', 0) | list | length == 0 - name: Set result to NON-COMPLIANT if any line is missing ansible.builtin.set_fact: rule_result: "NON-COMPLIANT" rule_output: "Some recommended lines are missing: {{ output.results | selectattr('found', 'equalto', 0) | map(attribute='item') | list | join(', ') }}" when: output.results | selectattr('found', 'equalto', 0) | list | length > 0
逻辑说明
- 使用Jinja2过滤器
selectattr筛选出所有found=0的结果项,通过list | length统计缺失行数量 - 当缺失行数量为0时,判定所有推荐行都存在,设置结果为
COMPLIANT - 当存在缺失行时,设置结果为
NON-COMPLIANT,并将缺失的行列表输出到rule_output中,便于直接定位问题
内容的提问来源于stack exchange,提问作者pavithra
相关产品推荐
相关产品推荐

