Ansible循环任务误执行于非目标主机问题求助
问题描述
- 运行环境:RHEL 9.4、Ansible 9.7、Python 3.11.7,采用
host_pinned策略 - 异常场景:单独执行Cisco(IOS/NX-OS/ASA)或FortiGate的SNMP任务文件均正常,但整合为站点级剧本同时部署时失效
- 核心问题:FortiGate的循环删除SNMP用户任务“溢出”到Cisco设备执行,触发
snmp_output未定义的报错——尽管任务已设置条件判断阻止跨设备执行
代码逻辑与现象
- FortiGate任务逻辑:先通过API调用获取所有SNMP用户信息并赋值给
snmp_output,再遍历该变量删除不符合命名规则的用户 - 差异现象:仅包含FortiGate任务的最小可复现剧本(MRE)单独运行时,Cisco设备不会执行FortiGate相关任务;但整合完整剧本后,Cisco设备(如switch1、switch2)会执行该循环删除任务
排查方向
条件判断的精准性与作用范围
- 检查FortiGate任务的
when条件是否严格匹配设备类型,比如是否用ansible_network_os == 'fortinet.fortios.fortios'这类精准判断,而非模糊的分组标签(若分组存在交叉会导致误触发) - 确认条件是否作用在整个任务块上:比如是否把获取
snmp_output和循环删除任务放在同一个block中并绑定when条件,避免循环任务脱离判断范围单独执行
- 检查FortiGate任务的
变量作用域与
host_pinned策略影响host_pinned策略下,变量可能在同一进程的主机间意外共享。检查snmp_output是否被定义为全局变量而非主机级变量,确保set_fact(若使用)未开启cacheable: yes,避免变量跨主机缓存- 排查是否有其他地方定义了同名
snmp_output变量,导致Cisco设备上该变量被意外赋值(即使未执行FortiGate的信息收集任务)
剧本结构与任务引用问题
- 检查完整剧本中任务的引用方式:使用
import_tasks或include_tasks时,是否将when条件正确绑定在引用语句上(如include_tasks: fortigate_snmp.yml when: ansible_network_os == 'fortinet.fortios.fortios'),而非仅写在任务内部导致部分任务漏判 - 核对inventory配置:确认Cisco设备未被错误归到fortigate组,或
ansible_network_os变量未被误设置为FortiGate类型
- 检查完整剧本中任务的引用方式:使用
Ansible版本特定bug排查
- 检查Ansible 9.7是否存在
when条件判断的已知bug,尤其是混合网络设备类型、使用host_pinned策略时的任务执行逻辑问题。可临时切换到linear策略测试,看是否还会出现任务溢出情况
- 检查Ansible 9.7是否存在
附相关代码与信息示例
最小可复现剧本(MRE)
- name: FortiGate SNMP User Management hosts: fortigate gather_facts: no tasks: - name: Get SNMP users fortinet.fortios.fortios_snmp_user_info: vdom: "root" register: snmp_output when: ansible_network_os == 'fortinet.fortios.fortios' - name: Delete non-standard SNMP users fortinet.fortios.fortios_snmp_user: vdom: "root" state: "absent" snmp_user: name: "{{ item.name }}" loop: "{{ snmp_output.meta.results | selectattr('name', 'match', '^non-standard-.*') | list }}" when: ansible_network_os == 'fortinet.fortios.fortios'
报错信息
fatal: [switch1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'snmp_output' is undefined\n\nThe error appears to be in '/path/to/fortigate_snmp.yml': line X, column Y, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n - name: Delete non-standard SNMP users\n ^ here\n"}
库存示例
[fortigate] fw1 ansible_host=10.0.0.1 ansible_network_os=fortinet.fortios.fortios [cisco] switch1 ansible_host=10.0.0.2 ansible_network_os=cisco.ios.ios switch2 ansible_host=10.0.0.3 ansible_network_os=cisco.nxos.nxos
内容的提问来源于stack exchange,提问作者Jeremy D
相关产品推荐
相关产品推荐

