Ansible Playbook 错误处理
当 Ansible 任务返回非 0 状态码时,任务执行失败,打印错误信息。
忽略错误
ignore_errors: true
可以忽略错误继续执行。
- name: Do not count this as a failure
ansible.builtin.command: /bin/false
ignore_errors: true
ignore_errors: true
支持在 Playbook 级别设置。
忽略无法访问主机错误
当主机因为某些原因无法访问时(节点临时重启),任务会执行失败,ignore_unreachable: true
可以忽略这个错误,以保证后续任务继续在这个节点执行。
- name: This executes, fails, and the failure is ignored
ansible.builtin.command: /bin/true
ignore_unreachable: true
- name: This executes, fails, and ends the play for this host
ansible.builtin.command: /bin/true
ignore_unreachable: true
支持在 Playbook 级别设置。
重置主机状态
当主机不可达时,主机会被标记为 UNREACHABLE
,meta: clear_host_errors
可以重置主机状态。
- name: This executes, fails, and the failure is ignored
ansible.builtin.command: /bin/true
- name: clear host errors
ansible.builtin.meta: clear_host_errors
- name: This executes, fails, and ends the play for this host
ansible.builtin.command: /bin/true
强制执行 handlers
当主机有任务执行失败时,会被踢出队列,如果主机有 handlers
任务,这些 handlers
任务不会被执行,通过 force_handlers: True
可以设置强制执行 handlers
。
除了
force_handlers: True
,在ansible.cfg
设置force_handlers = True
或 Ad-Hoc 添加--force-handlers
。
定义任务状态
failed_when 定义任务失败条件
通过 failed_when
可以设置任务失败条件,下边是一个例子:
- name: set when status is failed
ansible.builtin.command: ls /tmp/testdir
register: command_result
failed_when: >
(command_result.rc == 0) or
( 'No such' not in command_result.stderr)
- name: print var command_result
ansible.builtin.debug:
var: command_result
这个是个演示例子,表示如果 /tmp/testdir
目录存在,则任务失败。
failed_when
支持列表(列表相当于and
)。failed_when: - result.rc == 0 - '"No such" not in result.stderr'
可以查看
command_result
的内容来设置判断条件,command_result.rc
表示状态码,command_result.stderr
表示错误输出。
changed_when 定义任务变化条件
changed_when
可以设置任务在什么条件下处于 changed
条件,changed_when: false
表示永远为 ok
状态。
- name: set status when is changed
ansible.builtin.command: ls /tmp/testdir
register: command_result
changed_when: >
(command_result.rc != 0) or
( 'No such' in command_result.stderr)
failed_when: command_result.rc == 0
- name: set status always ok
ansible.builtin.command: id
changed_when: false
changed_when
同样支持列表(and
)。
changed_when
支持变量:
vars:
log_dir: /tmp/testdir
tasks:
- name: set status when is changed
ansible.builtin.shell: mkdir {{ log_dir }} || true
register: command_result
changed_when:
- 'command_result.stderr != "mkdir: cannot create directory ‘" ~ log_dir ~ "’: File exists"'
changed_when
里使用变量格式为 " ~ log_dir ~ "
。
确保 command 和 shell 模块成功
直接用官网的例子:
tasks:
- name: Run this command and ignore the result
ansible.builtin.shell: /usr/bin/somecommand || /bin/true
定义 Playbook 停止条件
any_errors_fatal
any_errors_fatal
可以设置只要有任务执行失败就停止 Playbook 的所有任务。
比方说在集群场景下,要求所有节点初始化配置都成功之后才能继续进行集群配置。
- name: test any errors fatal
hosts: all
become: true
gather_facts: false
any_errors_fatal: true
tasks:
- name: test any error fatal
ansible.builtin.shell: ls /tmp/testdir
- name: debug
ansible.builtin.debug:
msg: "Hello World!"
changed_when: false
any_errors_fatal
支持 Playbook、单个 Play 或 block 中使用。
在 block 中使用时,如果失败主机通过 rescue 中的任务救援成功,则后续任务会继续在失败主机进行。
[root@study ansible]# cat test.yml
- name: test any errors fatal
hosts: all
become: true
gather_facts: false
tasks:
- name: test any error fatal
block:
- name: ls /tmp/testdir
ansible.builtin.shell: ls /tmp/testdir
any_errors_fatal: true
rescue:
- name: rescue fail hosts
ansible.builtin.debug:
msg: "fix success!"
- name: debug
ansible.builtin.debug:
msg: "Hello World!"
changed_when: false
[root@study ansible]# ansible-playbook test.yml
PLAY [test any errors fatal] **************************************************************************************************************************************
TASK [ls /tmp/testdir] ********************************************************************************************************************************************
fatal: [serverb]: FAILED! => {"changed": true, "cmd": "ls /tmp/testdir", "delta": "0:00:00.005889", "end": "2025-06-23 17:00:53.031011", "msg": "non-zero return code", "rc": 2, "start": "2025-06-23 17:00:53.025122", "stderr": "ls: cannot access '/tmp/testdir': No such file or directory", "stderr_lines": ["ls: cannot access '/tmp/testdir': No such file or directory"], "stdout": "", "stdout_lines": []}
changed: [servera]
TASK [rescue fail hosts] ******************************************************************************************************************************************
ok: [serverb] => {
"msg": "fix success!"
}
TASK [debug] ******************************************************************************************************************************************************
ok: [servera] => {
"msg": "Hello World!"
}
ok: [serverb] => {
"msg": "Hello World!"
}
PLAY RECAP ********************************************************************************************************************************************************
servera : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
设置失败主机最大百分比
max_fail_percentage
可以设置一个批次有多少个主机任务失败时停止 Playbook。
---
- hosts: webservers
max_fail_percentage: 30
serial: 10
这个表示每批次执行 10 台主机,如果有 3 台以上(不包含 3)主机(30%)执行失败,则整个 Playbook 停止。
这里强调一点,
max_fail_percentage
要求失败主机百分比超过其设定值才会触发,按照上边的例子,只有每批次失败 4 台主机时 Playbook 才会停止。