Ansible:设置ignore_errors仍报变量未定义,如何在任务异常时定义变量?
解决Ansible中vSphere虚拟机检查任务失败及变量未定义问题
核心问题分析
你遇到的问题主要有两个:
- debug语法错误:使用
var: "{{ vm_fact }}"会导致Ansible解析异常,错误地将变量值当作变量名,从而提示"VARIABLE IS NOT DEFINED"。 - 任务失败控制不当:虽然添加了
ignore_errors: True和failed_when: 0 > 1,但需要确保循环中每个失败的项都被捕获并注册到变量中,同时避免整个任务失败。
修正后的Playbook
- name: check/power(on/off) hosts on vsphere hosts: localhost vars: decom_list: - vm1 - vm2 - vm3 tasks: - name: check hosts on vsphere vmware_guest_info: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" name: "{{ item }}" schema: vsphere datacenter: DC1 loop: "{{ decom_list }}" register: vm_fact # 忽略单个循环项的错误,确保任务继续执行 ignore_errors: True # 强制任务永远不标记为失败,确保vm_fact始终被注册 failed_when: false - name: 查看完整的vm_fact变量(修正debug语法) debug: var: vm_fact - name: 过滤出不存在的虚拟机 set_fact: non_existent_vms: "{{ vm_fact.results | selectattr('failed') | selectattr('msg', 'search', 'Unable to gather information for non-existing VM') | map(attribute='item') | list }}" - name: 更新decom_list,移除不存在的虚拟机 set_fact: decom_list: "{{ decom_list | difference(non_existent_vms) }}" - name: 查看更新后的decom_list debug: var: decom_list
关键修正点说明
Debug语法修正:
原debug任务中var: "{{ vm_fact }}"是错误写法,Ansible的debug模块var参数直接接收变量名,不需要模板包裹,正确写法为var: vm_fact。任务失败控制:
使用failed_when: false替代failed_when: 0 > 1,更清晰地强制任务不会失败;配合ignore_errors: True,确保循环中每个VM的检查结果(无论成功或失败)都会被注册到vm_fact.results中。过滤不存在的VM:
通过selectattr('failed')筛选出循环中失败的项,再通过search匹配特定错误信息,最后提取对应的VM名称,得到不存在的虚拟机列表。更新decom_list:
使用difference过滤器从原列表中移除不存在的VM,得到仅包含存在虚拟机的新列表,后续任务可基于此列表执行操作。
处理无msg属性的情况
部分失败项可能没有msg字段,可通过default过滤器避免条件检查失败:
- name: 过滤出不存在的虚拟机(兼容无msg字段的情况) set_fact: non_existent_vms: "{{ vm_fact.results | selectattr('failed') | selectattr('msg', 'search', 'Unable to gather information for non-existing VM', default=false) | map(attribute='item') | list }}"
这里通过default=false确保当msg不存在时,该条件返回false,不会抛出错误。
内容的提问来源于stack exchange,提问作者dfs
相关产品推荐
相关产品推荐

