Ansible模板带条件循环实现:仅筛选端口检测失败条目
问题根因
Ansible 带循环的任务注册变量返回结构中,顶层的failed是聚合状态标记:只要循环内任意一个条目执行失败,顶层failed就会被置为true,不代表所有循环条目都执行失败。
原有模板逻辑存在两个核心错误:
- 分支判断仅依赖顶层
failed值,进入失败分支后直接遍历全部检测结果,未做单条结果的状态筛选 - 循环输出时未判断每个检测结果自身的
failed属性,导致连通成功的端口也被错误列入未开放清单。
修正方案
直接在遍历检测结果时,按单条结果的failed属性做筛选即可,无需判断顶层聚合状态。
完整模板(同时展示成功/失败端口)
Port Checks: {% set failed_ports = server_port_check.results | selectattr('failed', 'equalto', true) | list %} {% set success_ports = server_port_check.results | selectattr('failed', 'equalto', false) | list %} {% if failed_ports | length > 0 %} The following ports are not open: {% for result in failed_ports %} Host: {{ result.item.name }} Port: {{ result.item.port }} Reason: {{ result.msg | default('Connection failed') }} {% endfor %} {% endif %} {% if success_ports | length > 0 %} The following ports are open: {% for result in success_ports %} Host: {{ result.item.name }} Port: {{ result.item.port }} {% endfor %} {% endif %}
精简模板(仅展示失败端口,无失败则输出全通提示)
如果只需要输出检测失败的端口项,可以用更简洁的写法:
Port Checks: {% for result in server_port_check.results if result.failed == true %} - Host: {{ result.item.name }}, Port: {{ result.item.port }}, Error: {{ result.msg }} {% else %} All checked ports are reachable. {% endfor %}
逻辑说明
- 使用
selectattr过滤器直接从results列表中筛选对应状态的检测条目,避免冗余的循环内判断 - 输出对应分类前先判断列表长度,不存在对应状态的端口时不会输出空标题
- 失败项额外返回错误原因字段,方便定位连通性故障原因
内容的提问来源于stack exchange,提问作者d1530
相关产品推荐
相关产品推荐

