ansible之playbook-04 handlers使用

playbook条件循环控制、handlers及失败处理

循环

可以使用item循环变量+loop模块组合使用,实现普通循环

1.变量放在loop下

---
- name: 一键操作
  hosts: centos70
  tasks:
    - name:  停止服务
      yum:
        name: "{{ item }}"     ##引用循环变量。
        state: present
      loop:              ##使用loop模块,要操作的对象列表。
        - nginx
        - vim

《ansible之playbook-04 handlers使用》

2.vars定义变量

定义变量,一键启动受控机上的两个服务。

---
- name: 一键操作
  hosts: centos70
  vars:
     service_name:
       - nginx
       - crond
  tasks:
    - name:  loop控制
      service:
        name: "{{ item }}"     ##引用循环变量。
        state: started
      loop: "{{ service_name }}"              ##使用loop模块,要操作的对象列表。

《ansible之playbook-04 handlers使用》

3.字典多变量循环

---
- name: 一键操作
  hosts: centos70
  vars:
     user_info:
      - user: 'test1'
        uid: '2000'
      - user: 'test1'
        uid: '2000'
  tasks:
    - name:  loop控制
      shell: |
        echo "{{ item.user }}" > /tmp/fortest
        echo "{{ item.uid }}" >> /tmp/fortest
      loop: "{{ user_info }}"              ##使用loop模块,要操作的对象列表。


也可以这样写
vars:  
    user_info:
      - {user:"test1",uid:"2000"}
      - {user:"test2",uid:"2000"}

《ansible之playbook-04 handlers使用》

4.loop+register

---
- name: 一键操作
  hosts: centos70
  vars:
     user_info:
      - 'test1'
      - 'test2'
  tasks:
    - name:  loop控制
      shell: |
        echo "{{ item }}" 真的喜欢你
      loop: "{{ user_info }}"              ##使用loop模块,要操作的对象列表。
      register: regist
    - name: Print
      debug:
        var: regist         ##打印输出

《ansible之playbook-04 handlers使用》

条件判断

  • 使用when语句来进行条件判断,若条件满足,则运行任务;若条件不满足,则跳过任务。
  • when语句放在模块及模块参数的后面。

使用when语句来进行条件判断,若条件满足,则运行任务;若条件不满足,则跳过任务。
when语句放在任务名称和模块同级。

条件 示例
等于(值为字符串或数字) max_memory == 512
小于/大于/小于等于/大于等于 min_memory < 128
不等于 min_memory != 512
变量存在 min_memory is defined
变量不存在 min_memory is not defined
布尔变量是真。1 或True或yes的值为True memory_available
布尔变量是假。0 或False或no的值为True not memory_available
变量的值是否在变量的列表中 ansible_distribution in supported_distros

1.根据某个变量的取值状态判断是否执行某个任务

---
- name: 卸载
  hosts: centos70
  vars:
    service_status: true
  tasks:
    - name: 判断nginx是否安装
      yum:
        name: nginx
        state: absent
      when: service_status 

《ansible之playbook-04 handlers使用》

---
- name: 卸载
  hosts: centos70
  vars:
    service_status: false
  tasks:
    - name: 判断nginx是否安装
      yum:
        name: nginx
        state: absent
      when: service_status

《ansible之playbook-04 handlers使用》

2.根据变量是否存在判断

---
- name: 卸载
  hosts: centos70
  vars:
          #service_status: false
  tasks:
    - name: 判断nginx是否安装
      yum:
        name: nginx
        state: present
      when: service_status  is defined


---
- name: 卸载
  hosts: centos70
  vars:
          service_status: false
  tasks:
    - name: 判断nginx是否安装
      yum:
        name: nginx
        state: present
      when: service_status  is defined

《ansible之playbook-04 handlers使用》

3.根据事实来判断

一般需要根据受控机的状态来判断是否进行某些操作

首先查看受控机的事实

ansible centos70 -m setup |less

《ansible之playbook-04 handlers使用》

当系统版本大于等于7.5时,才执行条件循环语句,依次停止变量列表中的服务。

---
- name: 测试
  hosts: centos70
  vars:
          service_name:
           - nginx
           - crond
  tasks:
    - name: 判断nginx启动
      service:
        name: "{{ item }}"
        state: started
      loop: "{{ service_name }}"
      when: ansible_distribution_version >="7.5"

《ansible之playbook-04 handlers使用》

根据上个任务结果判断

常见的一个值是rc,rc是任务执行后输出的一个值,当rc=0时,代表任务执行成功。

《ansible之playbook-04 handlers使用》

---
- name: 安装服务
  hosts: centos70
  tasks:
    - name: 判断服务是否安装
      yum:
        name: nginx
        state: present
      ignore_errors: yes   ##任务执行失败直接跳过,可以继续执行后面任务。
      register: regist     ##注入任务输出的结果

    - name: 启动服务
      service:
        name: nginx
        state: started
      when:
        - regist.rc == 0   ##变量qingjun里的内容有个rc值,rc=0时才会执行第二步。

《ansible之playbook-04 handlers使用》

《ansible之playbook-04 handlers使用》

多条件判断

当有多个条件的时候可以进行多条件判断,使用and或者or关键字

and用法,所有条件都满足才执行

单行写法
when: ansible_distribution_version == "7.5" and python_version > 2.7

多行写法
when:       
   - ansible_distribution_version == "7.5"      
   - python_version > 2.7

or用法,只要有一个条件满足即可执行

单行写法
when: ansible_distribution_version == "7.5" or python_version > 2.7

多行写法
when:       
    ansible_distribution_version == "7.5"    
    or
    python_version > 2.7

()组合写法,把一组表达式组合在一起,形成一个更大的表达式

 when:
        ( ansible_distribution == "CentOS" and ansible_distribution_major_version == "7")
         or
        ( ansible_distribution == "Fedora" and ansible_distribution_major_version == "28")
---
- name: 测试
  hosts: centos70
  vars:
          service_name:
           - nginx
           - crond
  tasks:
    - name: 判断nginx启动
      service:
        name: "{{ item }}"
        state: started
      loop: "{{ service_name }}"
      when:
        ( ansible_distribution == "CentOS" and ansible_distribution_major_version == "7")
         or
        ( ansible_distribution == "Fedora" and ansible_distribution_major_version == "28")

《ansible之playbook-04 handlers使用》

handlers处理程序

基本了解:

handlers和tasks功能一样,也是用于处理任务的,只是它用于任务完成后需要触发进行操作的情况。
handlers和tasks是同级别,需要在tasks任务里定义notify语句,当notify语句所在的任务结果显示为changed时,才会触发handlers任务。

注意事项:

  • 当tasks中有多个任务定义notify语句时,触发任务会按照handlers任务里的顺序来执行。
  • 若tasks中定义多个notify语句具备相同的名称时,最终只会触发一个handlers任务。
  • 即使有多个任务通知处理程序,该处理程序依然仅运行一次。如果没有任务通知处理程序,它就不会运行。
---
- name: 安装服务
  hosts: centos7
  tasks:
    - name: 判断服务是否安装
      yum:
        name: nginx
        state: present
      ignore_errors: yes

    - name: 更改服务配置文件
      template:
        src: nginx.conf             ##将主控机上的文件传到受控机上,若文件内容发生改变则触发任务。
        dest: /etc/nginx/nginx.conf
      notify:
       - restart nginx   ##需要与handlers名称一致。

    - name: 启动服务
      service:
        name: nginx
        state: started
  handlers:
    - name: restart nginx     ##需与notify名称一致。
      service:
        name: nginx
        state: restarted

《ansible之playbook-04 handlers使用》

《ansible之playbook-04 handlers使用》

《ansible之playbook-04 handlers使用》

任务失败处理方法

1.忽略失败的任务,继续执行

  • 添加参数ignore_errors: yes,可以让playbook在任务失败时继续执行。

2.强制执行失败任务

  • 添加参数force_handlers: yes,针对性的适用handlers处理程序的场景。

正常情况下,当某一个任务执行失败时就会停止其他程序处理;当使用此参数时,即时前面有任务执行失败,后面的handlers也会在notify函数所在的任务发生改变时正常执行。

---
- name: 安装服务
  hosts: centos70
  force_handlers: yes
  tasks:
    - name: 判断服务是否安装
      yum:
        name: nginx
        state: present
      ignore_errors: yes

    - name: 更改服务配置文件
      template:
        src: nginx.conf             ##将主控机上的文件传到受控机上,若文件内容发生改变则触发任务。
        dest: /etc/nginx/nginx.conf
      notify:
       - restart nginx   ##需要与handlers名称一致。

    - name: 启动服务
      service:
        name: nginx1111
        state: started
  handlers:
    - name: restart nginx     ##需与notify名称一致。
      service:
        name: nginx
        state: restarted

《ansible之playbook-04 handlers使用》

《ansible之playbook-04 handlers使用》

3.自定义报错显示信息

  • 使用failed_when指定任务失败条件,再使用fail模块指定要输出的错误信息。
  • 常用于输出的错误信息太多,而我们只需要简短的错误提示即可。或者是运行的脚本里有多个任务,但其中有个任务执行失败但最终输出的信息还是changed,并非一片飘红。
#!/bin/bash
echo "failtest" >/tmp/shadow.txt
cat kskdkdks         ##任务执行失败。
ls /tmp/shadow.txt  ##任务执行成功

---
- name: 测试
  hosts: centos70
  gather_facts: no   ##关闭收集事实。
  tasks:
    - name: 脚本测试
      script: script.sh  
      register: regist
    - debug:
        var: regist

《ansible之playbook-04 handlers使用》

自定义报错信息

---
- name: 测试
  hosts: centos70
  gather_facts: no   ##关闭收集事实。
  tasks:
    - name: 脚本测试
      script: script.sh
      register: regist
    - name: 自定义错误信息
      fail:
         msg: "No such file or directory,请立即检查脚本!!!"
      failed_when: "'No such file or directory' in regist.stdout"

《ansible之playbook-04 handlers使用》

4.自定义“changed”出现

  • 特殊场景时需要playbook输出信息一直是changed,或是ok,可以使用。

如下使用template模块时,文件发生改动或第一次发送到受控机会发生改变则输出changed,之后文件不修改则一直输出ok。

此时如果要后面的输出信息一直是changed,只需在模块同级添加 changed_when,为True时则输出changed。

---
- name: 安装服务
  hosts: centos70
  force_handlers: yes
  tasks:
    - name: 更改服务配置文件
      template:
        src: nginx.conf             ##将主控机上的文件传到受控机上,若文件内容发生改变则触发任务。
        dest: /etc/nginx/nginx.conf

      changed_when: true
      notify:
       - restart nginx   ##需要与handlers名称一致。

  handlers:
    - name: restart nginx     ##需与notify名称一致。
      service:
        name: nginx
        state: restarted

可以看到没有添加 changed_when: true时,运行template时没有changed,添加后任务状态为changed,进而运行了handlers,所以出现了3个ok

《ansible之playbook-04 handlers使用》

Ansible块和错误处理

基本了解:

  • block:block块中的任务是绑定在一起的,要么一起执行,要么一起不执行。
  • rescue:定义要在block子句中定义的任务失败时运行的任务。
  • always:不论block和rescue子句中定义的任务是成功还是失败都执行。

若block块中存在任意一个失败任务,随后会执行rescue块中的任务。block成功执行,则rescue不会执行;always始终执行。

---
- name: 测试
  hosts: centos70
  gather_facts: no
  tasks:
    - name: blocktest
      block:
      - name: block任务
        command: echo "block"
      - name: 失败任务
        command: ls shadowwu
      rescue:
      - name: rescue任务
        command: echo "rescue"
      always:
      - name: always任务
        command: echo "always"
---
- name: 测试
  hosts: centos70
  gather_facts: no
  tasks:
    - name: blocktest
      block:
      - name: block任务
        command: echo "block"
      - name: 成功任务
        command: echo "success"
      rescue:
      - name: rescue任务
        command: echo "rescue"
      always:
      - name: always任务
        command: echo "always"

《ansible之playbook-04 handlers使用》

参考

Ansible基础5——条件语句、循环语句、handlers、任务失败处理_ansible handlers-CSDN博客

点赞

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注