ansible系列(28)--ansible的playbook异常处理



1. playbook的异常处理

1.1 Playbook错误忽略

playbook 执行的过程中,难免会遇到一些错误(返回结果不为0)。由于 playbook 遇到错误后,不会执行之后的任务,不便于调试,此时,可以使用 ignore_errors 来暂时忽略错误,使得 playbook 继续执行。

  • 首先编写一个playbook文件:

    [root@xuzhichao playbook]# cat ignore.yml
    - hosts: localhost
      tasks:
        - name: Igonre False
          shell: /bin/false    <==此命令返回值一定不为0
    
        - name: Print Message
          debug:
            msg: "It's hard to here"
    
  • 此时运行playbook时会在Igonre False任务中报错,无法继续向下运行:

    [root@xuzhichao playbook]# ansible-playbook ignore.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [Igonre False] *******************************************************************************************************************************************
    fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.024018", "end": "2021-08-05 21:36:36.638534", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 21:36:36.614516", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
    
    PLAY RECAP ****************************************************************************************************************************************************
    localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
    
  • 修改playbook文件,忽略中间task的错误,继续向下执行:

    [root@xuzhichao playbook]# cat ignore.yml
    - hosts: localhost
      tasks:
        - name: Igonre False
          shell: /bin/false
          ignore_errors: yes
    
        - name: Print Message
          debug:
            msg: "It's hard to here"
    
  • 此时运行playbook会忽略掉中间task的错误,继续向下运行:

    [root@xuzhichao playbook]# ansible-playbook ignore.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [Igonre False] *******************************************************************************************************************************************
    fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.004268", "end": "2021-08-05 21:37:16.630140", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 21:37:16.625872", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
    ...ignoring      <==忽略错误
    
    TASK [Print Message] ******************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "It's hard to here"
    }
    
    PLAY RECAP ****************************************************************************************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1
    
  • 也可以写成下面的形式来保证task的返回值为0

    - hosts: localhost
      tasks:
        - name: Igonre False
          shell: /bin/false || /bin/ture
    
        - name: Print Message
          debug:
            msg: "It's hard to here"
    

1.2 task执行失败强制调用handlers

通常情况下,当 task 失败后, playbook 将会终止,任何在前面已经被 tasks notifyhandlers 都不会被执行。如果你在 playbook 中设置了 force_handlers: yes 参数,被通知的 handlers 就会被强制执行。

  • 请看下面的playbook

    [root@xuzhichao playbook]# cat force_handlers.yml
    - hosts: localhost
    
      tasks:
        - name: Copy Configure File
          template:
            src: conf/nginx.conf.j2
            dest: /tmp/nginx.conf
          notify: Start Nginx
    
        - name: Igonre False
          shell: /bin/false
    
      handlers:
        - name: Start Nginx
          service:
            name: nginx
            state: started
    
  • conf/nginx.conf.j2文件发生改变时,由于在 Igonre False这个task中执行出现错误,将不会执行handlers中的内容。

    [root@xuzhichao playbook]# ansible-playbook force_handlers.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [Copy Configure File] ************************************************************************************************************************************
    ok: [localhost]
    
    TASK [Igonre False] *******************************************************************************************************************************************
    fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.006289", "end": "2021-08-05 22:09:40.799988", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 22:09:40.793699", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
    
    PLAY RECAP ****************************************************************************************************************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0 
    
  • 若此时需要强制执行handlers中的内容,需要使用force_handlers: yes 参数,playbook修改如下:

    [root@xuzhichao playbook]# cat force_handlers.yml
    - hosts: localhost
      force_handlers: yes
    
      tasks:
        - name: Copy Configure File
          template:
            src: conf/nginx.conf.j2
            dest: /tmp/nginx.conf
          notify: Start Nginx
    
        - name: Igonre False
          shell: /bin/false
    
      handlers:
        - name: Start Nginx
          service:
            name: nginx
            state: started
    
  • 此时运行playbook,当conf/nginx.conf.j2文件发生改变时,handlers将会被强制执行:

    [root@xuzhichao playbook]# ansible-playbook force_handlers.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [Copy Configure File] ************************************************************************************************************************************
    changed: [localhost]
    
    TASK [Igonre False] *******************************************************************************************************************************************
    fatal: [localhost]: FAILED! => {"changed": true, "cmd": "/bin/false", "delta": "0:00:00.003843", "end": "2021-08-05 22:12:00.335807", "msg": "non-zero return code", "rc": 1, "start": "2021-08-05 22:12:00.331964", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
    
    RUNNING HANDLER [Start Nginx] *********************************************************************************************************************************
    ok: [localhost]
    
    PLAY RECAP ****************************************************************************************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
    

1.3 控制Tasks报告状态为OK

有时一些task会在每次playbook运行是都会执行一次,这样会导致playbook的运行结果中该task会显示为changed状态,但是有时这些task并没有改变被控端的状态,仅仅是获取了某些信息,此时可以使用changed_when: false 来抑制这个状态。

请看下面示例:

  • playbook文件内容如下:

    [root@xuzhichao playbook]# cat status_ok.yml
    - hosts: localhost
      tasks:
        - name: Get Nginx Server Port
          shell: netstat -ntlp | grep nginx
          register: nginx_port
    
        - name: Print Nginx Port
          debug:
            msg: 
              - "{{ nginx_port.stdout_lines }}"
    
  • 每次的执行结果“Get Nginx Server Port”任务状态都是changed:

    [root@xuzhichao playbook]# ansible-playbook status_ok.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [Get Nginx Server Port] **********************************************************************************************************************************
    changed: [localhost]     <==状态为changed
    
    TASK [Print Nginx Port] ***************************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            [
                "tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      26579/nginx: master "
            ]
        ]
    }
    
    PLAY RECAP ****************************************************************************************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
  • 可以使用changed_when: false 来抑制这个状态,playbook修改如下:

    [root@xuzhichao playbook]# cat status_ok.yml
    - hosts: localhost
      tasks:
        - name: Get Nginx Server Port
          shell: netstat -ntlp | grep nginx
          register: nginx_port
          changed_when: false     <==该task不再发生changed提示
    
        - name: Print Nginx Port
          debug:
            msg: 
              - "{{ nginx_port.stdout_lines }}"
    
  • 此时执行结果如下:

    [root@xuzhichao playbook]# ansible-playbook status_ok.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [Get Nginx Server Port] **********************************************************************************************************************************
    ok: [localhost]     <==变为OK状态
    
    TASK [Print Nginx Port] ***************************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            [
                "tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      26579/nginx: master "
            ]
        ]
    }
    
    PLAY RECAP ****************************************************************************************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

1.4 changed_when检查任务结果

仍然以安装httpd为例,在每次修改完httpd的配置文件后,都需要检查配置文件的语法是否正确,如果不正确,则退出后续task,不重启httpd服务。

  • playbook文件优化如下:

    [root@xuzhichao playbook]# cat change_when.yml
    ---
    - hosts: 192.168.20.23
      remote_user: root
    
      tasks:
        - name: Install Htttpd Server
          yum:
            name: httpd
            state: present
          tags:
            - install_httpd
            - install_apache
    
        - name: Configure Httpd Server
          copy: 
            src: conf/httpd.conf.j2
            dest: /etc/httpd/conf/httpd.conf
            owner: "root"
            group: "root"
            mode: "0644"
          notify: Restart Httpd Server
          tags: conf_httpd
    
        - name: Check Httpd Configuer        <==检测配置文件语法
          shell: /usr/sbin/httpd -t
          register: httpd_check
          changed_when:
            - httpd_check.stdout.find('OK')  <==查找变量返回的结果是否有ok,如不存在则终止该tasks
            - false     <==被管理主机没有发生变化状态则为OK
    
        - name: Init Httpd Server
          copy:
            src: file/test.html.j2
            dest: /var/www/html/test.html
            owner: "apache"
            group: "apache"
            mode: "0644"
          tags: init_httpd
    
        - name: Start Httpd Server
          service:
            name: httpd
            state: started
            enabled: yes
          tags: start_httpd
    
      handlers:
        - name: Restart Httpd Server
          service:
            name: httpd
            state: restarted
          tags: restart httpd
          
    
    [root@nginx03 ~]# httpd -t
    Syntax OK      
    

    playbook运行结果如下:

    [root@xuzhichao playbook]# ansible-playbook change_when.yml 
    
    PLAY [192.168.20.23] ******************************************************************************************************************************************
    
    TASK [Install Htttpd Server] **********************************************************************************************************************************
    ok: [192.168.20.23]
    
    TASK [Configure Httpd Server] *********************************************************************************************************************************
    ok: [192.168.20.23]
    
    TASK [Check Httpd Configuer] **********************************************************************************************************************************
    ok: [192.168.20.23]
    
    TASK [Init Httpd Server] **************************************************************************************************************************************
    ok: [192.168.20.23]
    
    TASK [Start Httpd Server] *************************************************************************************************************************************
    changed: [192.168.20.23]
    
    PLAY RECAP ****************************************************************************************************************************************************
    192.168.20.23              : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
posted @ 2021-08-18 17:39  向往自由的独行者  阅读(1772)  评论(0编辑  收藏  举报