实施ansible控制任务

实施任务控制

编写循环和条件任务

##简单循环
1.不用循环

---
- name: test
  hosts: web
  tasks:
          - name: Apache is runing
            service:
                    name: httpd
                    state: started
          - name: vsftpd is running
            service:
                    name: vsftpd
                    state: started

2.使用循环

 tasks:
          - name: apache and vsftpd is running
            service:
                    name: "{{ item }}"         循环变量 item
                    state: started
            loop:
                    - httpd
                    - vsftpd

在这里插入图片描述
3.将变量放入列表

  vars:
          web_service:
                  - httpd
                  - vsftpd
  tasks:
          - name: apache and vsftpd is running
            service:
                    name: "{{ item }}"
                    state: started
            loop: "{{ web_service }}"

在这里插入图片描述

循环散列或字典列表

---
- name: test
  hosts: web
  user:
          name: "{{ item.user }}"
          state: present
          group: "{{ item.group }}"
  loop:  
          - name: westos
            group: westos
          - name: caoaoyuan
            group: root

##早些版本的循环,使用 with_item

- name: test
  hosts: web
  vars:
          data:
                  - user1
                  - user2
                  - user3
  tasks:
          - name: "with_item"

register 和 loop 一起使用

---
- name: loop register test
  hosts: localhost
  gather_facts: no
  tasks:
          - name: loop task
            shell: "echo this is my {{ item }}"
            loop:
                    - one
                    - two
            register: echo_results         #注册变量
            
          - name: show results
            debug:
                    var: echo_results       #显示变量结果

在这里插入图片描述
##迭代上面 playbook 的结果(即使用上面 item 的结果)

---
- name: loop register test
  hosts: localhost
  gather_facts: no
  tasks:
          - name: loop task
            shell: "echo this is my {{ item }}"
            loop:
                    - one
                    - two
            register: echo_results

          - name: show results
            debug:
                    msg: "STDOUT is : {{ item.stdout }}"
            loop: "{{ echo_results['results'] }}"

在这里插入图片描述

条件任务语法

关键字:when
使用布尔值测试

- name: BOOL test
  hosts: all
  vars:
          my_task: true          
  tasks:  
          - name: httpd is installed
            yum:
                    name: httpd
            when: my_task        # 只有当变量为 true 时,才会执行

在这里插入图片描述
当值为false时
在这里插入图片描述
在这里插入图片描述
就跳过了这一步。

测试 my_service 变量是否有值,有值则安装

---
- name: BOOL test
  hosts: all
  vars:
          my_service: httpd
  tasks:
          - name: "{{ my_service }} is installed”
            yum:
                    name: "{{ my_service }}"
            when: my_service is defined

在这里插入图片描述
没有问题,当没有定义变量时则会报错,编写有问题。

##条件

等于(字符串) A == “B”
等于(数字) A == 100
小于 <
大于 >
小于等于 <=
大于等于 >=
不等于 !=
变量存在 xxx is defined
变量不存在 xxx is not defined
布尔值 true 1、true、yes
布尔值 false 0、false、no
第一个变量的值存在,且在第二个变量的列表中 A in B
or 两个条件一个为真即可
and 两个条件必须都为真

##组合循环和有条件任务
示例1:

-
- name: keyword
  hosts: all
  tasks:
          - name: install mariadb
            yum:
                    name: mariadb-server
                    state: latest
            loop: "{{ ansible_mounts }}"        #这个变量是事实,已知的
            when: item.mount == "/" and item.size_available > 300000000

当 item.mount 等于 / 且 size大小大于 3000000000k 时执行。
在这里插入图片描述
在这里插入图片描述
可见已经安装了mariadb。

示例 2:
当 vsftpd 正在运行时重启 httpd 服务。

---
- name: restart vsftpd if vsftpd is running
  hosts: all
  tasks:
          - name: grt vsftpd status
            commond: /usr/bin/systemctl is-active vsftpd         判断状态
            ignore_errors: yes               如果 vsftpd 没运行或失败,则忽略错误,继续执行。
            register: result               定义变量保存结果
          - name: restart apache
            service:
                    name: httpd
                    state: restarted
            when: result.rc == 0   返回码为0代表正常运行,为1则代表有错误。

在这里插入图片描述
在这里插入图片描述
且httpd已经重新启动。当vsftpd关闭时:
在这里插入图片描述

##编写循环和条件任务:
在这里插入图片描述

 vim  db.yml
---
- name: mariadb is tunning
  hosts: web2
  vars:
          mariadb_pkg:
                  - mariadb-server
                  - python3-PyMySql
  tasks:
          - name: mariadb is installed
            yum:
                    name: "{{ item }}"
                    state: present
            loop: "{{ mariadb_pkg }}"
            when: ansible_distribution  == "RedHat"

受管主机使用 rehdat 操作系统时才执行。

#检测 westos2 组的主机系统
在这里插入图片描述
#运行
在这里插入图片描述

实施处理程序

处理程序是响应由其他任务触发的通知的任务
#只有在 template 任务通知已发生更改时才会触发
在这里插入图片描述
即这块changed有数字的时候才触发。

---
- name: Tesy
  hosts: web1
  tasks:
          - name: copy file
            template:
                    src: files/example.conf
                    dest: /etc/httpd/conf.d/example.conf
            notify:                          notify 语句指出该任务需要触发一个处理程序
                    - restart apache         程序名
                    - restart mysql
  handlers:                                  表示处理程序任务列表的开头
          - name: restart apache             被任务调用的处理程序名称
            service:                         处理该程序的模块
                    name: httpd
                    state: restarted
          - name: restart mysql
            service:
                    name: mariadb
                    state: restarted


#ansible 把 notify 语句当作数组

mkdir files
cat files/example.conf

在这里插入图片描述
执行:
在这里插入图片描述
#使用处理程序注意:

  1. 处理程序始终按照 play 的 handlers 部分指定的顺序运行,不按 notify 里的
  2. 处理程序通常在相关 play 中所有其他任务运行完后运行
  3. 处理程序名称存在于个 play 命名空间中(如果两个处理程序同名,只会运行一个)
  4. 如果多个任务通知处理程序,处理程序也只会运行一次
  5. 如果包含 notify 的语句任务没有报告 changed 结果,则处理程序不会获得通知

例如再次执行TTest.yml,
在这里插入图片描述
就没有执行处理程序,因为文件已经复制过了,没有changed了,所以没有调用处理程序。

处理任务失败

通常 playbook 遇到错误会中止执行,但是有时我们想要失败时也继续执行下面的play

忽略任务失败

关键字:ignore_errors
#举例
先不添加 ignore_errors

- name: test
  hosts: all
  tasks:
          - name: tset
            yum:
                    name: k8s
                    state: latest

执行:
在这里插入图片描述
会直接报错退出。
加上后:

---
- name: test
  hosts: all
  tasks:
          - name: tset
            yum:
                    name: k8s
                    state: latest
            ignore_errors: yes

在这里插入图片描述
还会继续往下走。

任务失败后强制执行处理程序

通常任务失败,play 会中止,那么收到 play 中之前任务通知的处理程序将不会运行,如果要运
行,需要使用关键字:force_handlers:yes
#举例=

ts: all
  #  force_handlers: yes              先把它注释掉
  tasks:
          - name: always notify
            command: /bin/true
            notify: restart apache
          - name: fail task
            yum:
                    name: k8s
                    state: latest
                    
  handlers:         
          - name: restart apache
            service:
                    name: httpd
                    state: restarted

执行:
在这里插入图片描述
执行到失败任务就直接退出了,不会执行 handlers 的内容,当我们去掉注释时:
在这里插入图片描述
在这里插入图片描述
强制执行handlers ,即使上面有错误。

指定任务失败条件

关键字:failed_when

tasks:
  - name: Run Script
   shell: /usr/local/bin/user.sh
   register: command_result
   failed_when: "'failure' in command_result.stdout"       fail 模块可以实现此效果
---
- name: test
  hosts: all
  tasks:
          - name: run script
            shell: /user/local/bin/user.sh
            register: command_result
            ignore_errors: yes
            
          - name: report failer
            fail:                 fail 模块可以提供明确消息
                    msg: "Authentication failure"
            when: "'failure' in command_result.stdout"

指定任务何时报告"Changed"结果

关键字:changed_when

- name: get time
  shell: date
  changed_when: false

当错误时才报告changed,由于date的输出每秒都在变化,我们加上changed_when 就可以不报告他的changed

ansible 块和错误处理

三种关键字:
block:定义要运行的主要任务
rescue:定义要在 block 子句中定义的任务失败时运行的任务
always:定义时中独立运行的任务
#练习:
故意制造错误

- name: Task Failure
  hosts: webservers
  vars:
    web_pkg: http      这里有错误,应该为httpd
    db_pkg: mariadb-server
    db_service: mariadb
  tasks:
    - name: Install {{ web_pkg }} packages
      yum:
        name: "{{ web_pkg }}"
        state: present
    - name: Install {{ db_pkg }} packages
      yum:
        name: "{{ db_pkg }}"
        state: present

运行报错
在这里插入图片描述
可见第一个任务失败,第二个任务不运行。

#那我们可以添加忽略关键字 : ignore_errors: yes

  tasks:
    - name: Install {{ web_pkg }} packages
      yum:
        name: "{{ web_pkg }}"
        state: present
         ignore_errors: yes
    - name: Install {{ db_pkg }} packages
      yum:
        name: "{{ db_pkg }}"
        state: present

这样即便安装apache报错,也会执行下面的任务

#还可以使用 block、rescue、always 将任务分开

---
- name: Task failure
  hosts: web
  vars:
    web_pkg: http
    db_pkg: mariadb-server
    db_service: mariadb
  tasks:
    - name: test install
      block:
        - name: install "{{ web_pkg }}"
          yum:
            name: "{{ web_pkg }}"
            state: present
      rescue:
        - name: Install {{ db_pkg }} packages
          yum:
            name: "{{ db_pkg }}"
            state: present
      always:
        - name: "{{ db_service }}"
          service:
            name: "{{ db_service }}"
            state: started

意为如果block块执行失败,则会执行rescue,单always 部分内容总会执行。
执行结果有报错,但是 mariadb 正常启动
在这里插入图片描述
#再修改,将 http 的包改为正确的httpd
在这里插入图片描述
发现 rescue 部分被忽略,但是 always 总会执行。

#控制’changed’条件

--
- name: Task failure
  hosts: web
  vars:
    web_pkg: httpd
    db_pkg: mariadb-server
    db_service: mariadb
  tasks:
    - name: check time           新添加的
      command: date
      register: command_result
    - name: print time           新添加的
      debug:
        var: command_result.stdout
    - name: test install
      block:
        - name: install "{{ web_pkg }}"
          yum:
            name: "{{ web_pkg }}"
            state: present
      rescue:
        - name: Install {{ db_pkg }} packages
          yum:
            name: "{{ db_pkg }}"
            state: present
      always:
        - name: "{{ db_service }}"
          service:
            name: "{{ db_service }}"
            state: started

运行发现 check time 任务每次执行是 changed
在这里插入图片描述
在这里插入图片描述
由于每次chenged都会触发处理程序,所以我们不想让他每次都为changed。
修改文件
在这里插入图片描述
再次运行,变为 ok
在这里插入图片描述
#使用 failed_when 关键字进行更改。
在这里插入图片描述
让httpd安装完成之后定义为失败,就可以让block和resuce中的任务都执行了。
运行
在这里插入图片描述
有报错,但是其实已经安装了 httpd 包,failed_when 关键字只是改变了任务的执行状态,没
有改变任务本身
但是失败的状态可以让 rescue 语句块执行

#总结:
1.循环迭代的方法
2.条件用于仅再符合特定条件时执行任务或 play
3.处理程序用法
4.只有任务报告受管主机做了更改,才会通知处理程序
5.处理任务失败,即使成功的任务也可以标记为失败
6.块用于将任务分组为单元,通过任务是否成功来确定执行其他任务与

发布了50 篇原创文章 · 获赞 18 · 访问量 3780

猜你喜欢

转载自blog.csdn.net/thermal_life/article/details/105393103