Ansible任务失败处理

在Ansible中,任务失败处理是一个重要的功能,可以帮助我们在任务执行过程中处理各种异常情况。以下是几个更详细的示例及其解释。

1. 忽视错误

- name: 忽略错误并继续执行后续任务
  hosts: web
  tasks:
    - name: 停止错误服务
      service:
        name: invalid_service_name
        state: stopped
      ignore_errors: yes

    - name: 确保httpd服务已启动
      service:
        name: httpd
        state: started
  1. 第一个任务尝试停止一个不存在的服务 invalid_service_name,由于使用了 ignore_errors: yes,即使任务失败,playbook也会继续执行后续任务。
  2. 第二个任务确保 httpd 服务已启动,无论第一个任务是否成功,这个任务都会执行。

2. 强制执行处理程序

- name: 强制执行处理程序
  hosts: web
  force_handlers: yes
  tasks:
    - name: 停止httpd服务
      service:
        name: httpd
        state: stopped
      notify: restart vsftpd

    - name: 执行错误命令
      command: invalid_command

  handlers:
    - name: restart vsftpd
      service:
        name: vsftpd
        state: restarted
  1. 设置 force_handlers: yes,即使任务失败,处理程序也会被执行。
  2. 尝试执行一个错误的命令 invalid_command,此任务必定失败。
  3. 即使 invalid_command 任务失败,notify 通知的 restart vsftpd 处理程序仍然会执行,重启 vsftpd 服务。

3. 使用 failed_when 指定任务失败条件

tasks:
  - name: 运行用户创建脚本
    shell: /usr/local/bin/create_users.sh
    register: command_result
    failed_when: "'Password missing' in command_result.stdout"
  1. 运行用户创建脚本,将结果注册到变量 command_result
  2. 使用 failed_when 指定任务失败条件,如果 command_result.stdout 中包含 "Password missing",则任务标记为失败。
tasks:
  - name: 创建用户并检查结果
    shell: /usr/local/bin/create_users.sh
    register: command_result
    failed_when: "'Password missing' in command_result.stdout"

  - name: 报告脚本失败
    fail:
      msg: "创建用户失败:密码缺失"
    when: "'Password missing' in command_result.stdout"
  1. 第一个任务运行用户创建脚本并检查结果。
  2. 第二个任务在检测到错误时,使用 fail 模块报告详细错误信息。

4. 使用 changed_when 控制任务变更报告

tasks:
  - name: 升级数据库
    shell: /usr/local/bin/upgrade_database.sh
    register: command_result
    changed_when: "'Upgrade successful' in command_result.stdout"
    notify:
      - restart_database

handlers:
  - name: restart_database
    service:
      name: mariadb
      state: restarted
  1. 运行数据库升级脚本,并将结果注册到变量 command_result
  2. 使用 changed_when 控制任务变更报告,如果 command_result.stdout 中包含 "Upgrade successful",则任务报告为已更改。
  3. 如果任务报告更改,将通知处理程序 restart_database
tasks:
  - name: 升级数据库
    shell: /usr/local/bin/upgrade_database.sh
    register: command_result
    changed_when: "'Upgrade successful' in command_result.stdout"
    failed_when: "'Upgrade failed' in command_result.stdout"
    notify:
      - restart_database

handlers:
  - name: restart_database
    service:
      name: mariadb
      state: restarted
  1. 第一个任务运行数据库升级脚本,并检查结果。
  2. 使用 changed_whenfailed_when 控制任务的变更和失败条件。
  3. 如果任务报告更改,将通知处理程序 restart_database

5. 块和错误处理

- name: 使用block和rescue处理错误
  hosts: web
  tasks:
    - name: 块任务
      block:
        - name: 尝试运行一个可能失败的命令
          command: /usr/local/bin/possibly_failing_command

      rescue:
        - name: 错误处理任务
          debug:
            msg: "命令执行失败,执行救援任务"

      always:
        - name: 总是执行的任务
          debug:
            msg: "这将总是执行,不管前面的任务是否成功"
  1. 使用 block 组定义了一组任务,如果其中任何任务失败,则执行 rescue 中定义的救援任务。
  2. 不论 blockrescue 中的任务结果如何,always 中的任务总是会被执行。
- name: 使用block、rescue和always处理错误
  hosts: web
  tasks:
    - name: 块任务
      block:
        - name: 创建用户
          shell: /usr/local/bin/create_user.sh
          register: create_user_result
          failed_when: "'User creation failed' in create_user_result.stdout"

        - name: 分配权限
          shell: /usr/local/bin/assign_permissions.sh
          register: assign_permissions_result
          changed_when: "'Permissions assigned' in assign_permissions_result.stdout"

      rescue:
        - name: 用户创建失败,执行救援任务
          debug:
            msg: "用户创建失败,执行救援任务"

      always:
        - name: 总是执行的任务
          debug:
            msg: "这将总是执行,不管前面的任务是否成功"
  1. block 中定义两个任务:创建用户和分配权限。
  2. 如果 create_user.sh 任务失败,执行 rescue 中的救援任务。
  3. 不论 blockrescue 中的任务结果如何,always 中的任务总是会被执行。

在Ansible中处理任务失败的方式,包括忽视错误、强制执行处理程序、使用 failed_whenchanged_when 控制任务的结果,以及通过 blockrescuealways 处理复杂的错误场景。通过这些机制,我们可以更灵活地管理和处理任务执行过程中可能出现的各种异常情况。

本文由mdnice多平台发布


逼格高的汤圆
10 声望2 粉丝