Ansible—实施任务控制

Ansible循环(loop)

  1. 简单循环
  • 不用循环时编写playbook
[root@localhost ~]# cat test.yml 
---
- name: test
  hosts: all 
  tasks:
    - name: apche 
      service: 
        name : httpd 
        state: started
     - name: vsftpd
       service :
         name: vsftpd
         state: started

当使用循环变量item编写

[root@localhost ~]# cat test.yml 
---
- name: test
  hosts: all 
  tasks:
    - name: apche and vsftpd
      service: 
        name : '{{ item }}'
        state: started
        loop :
          - httpd
          - vsftpd  

将变量放入列表

[root@localhost ~]# cat test.yml 
---
- name: test
  hosts: all 
  vars: 
    service: 
      - httpd
      - vsftpd
  tasks:
    - name: apche and vsftpd
      service: 
        name: '{{ item }}'
        state: started
        loop: '{{ service }}'  

2.循环散列或字典列表

---
- name: Users exist and are in the correct groups
  user:
    name: "{{ item.name }}"
    state: present
    groups: "{{ item.groups }}"
  loop:
    - name: jane
      groups: wheel
    - name: joe
      groups: root

较早样式的循环关键字
with_items的示例如下所示:

vars:
  data:
    - user0
    - user1
    - user2
tasks:
  - name: "with_items"
    debug:
      msg: "{{ item }}"
    with_items: "{{ data }}"

3.注册变量与loop

---
- name: loop register test
  gather_facts: no	
  hosts: localhost
  tasks:
    - name: loop echo task
      shell: "echo This is my item: {{ item }}"
      loop:
        - one
        - two
      register: echo_results			#注册变量
    - name: Show echo results variable
      debug:
        var: echo_results			#显示变量结果
[root@localhost ~]# cat AA.yml 
---
- name: test
  hosts: all
  gather_facts: no
  tasks:
    - name: delete user
      shell: "echo {{ item }}"
      loop: 
        - one
        - two
      register: result

    - name: print
      debug:
        msg: "{{ result.results }}"
                                   

Ansible条件判断(when)

条件判断:

when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行

常见判断符号:
等于(字符串) A == “B”
等于(数字) A == 100
小于 <
大于 >
小于等于 <=
大于等于 >=
不等于 !=
变量存在 xxx is defined
变量不存在 xxx is not defined
布尔值 true 1、true、yes
布尔值 false 0、false、no
第一个变量的值存在,且在第二个变量的列表中 A in B

  • 测试多个条件: or:两个条件一个为真即可;and:两个条件必须都为真
  • when 支持使用列表描述条件:
when:
  - ansible_distribution_version == "8.0"
  - ansible_kernel == "4.18.0-80.1.2.el8_0.x86_64"
######再如:########
when:
  ( ansible_distribution == "RedHat" and ansible_distribution_major_version == "8" )
  or
  ( ansible_distribution == "CentOS" and ansible_distribution_major_version== "7" )

组合循环和有条件的任务

  • 示例:只有当vsftpd服务运行时,才能重启Apache
---
- name: 当vsftpd服务运行时,重启Apache hosts: all
  tasks:
    - name: get vsftpd status
      command: /usr/bin/systemctl is-active vsftpd	#判断状态
      ignore_errors: yes	#如果vsftpd没运行或失败,则忽略,继续执行下面动作
      register: result		#定义变量保存结果
    - name: Restart httpd
      service:
        name: httpd
        state: restarted
      when: result.rc == 0  	#退出码为0,则重启httpd

实施处理程序

处理程序是响应由其他任务触发的通知的任务
处理程序任务列表的开头:handlers

1. 示例:处理程序

只有在 template 任务通知已发生更改时才会触发

---
- name: test
  hosts: all
  tasks:
    - name: 复制文件
      template:
        src: files/example.conf     #需要在当前目录中编写源配置文件
        dest: /etc/httpd/conf.d/example.conf
      notify:                        #notify 语句指出该任务需要触发一个处理程序
        - restart apache             #程序名
        - restart vsftpd
  handlers:                          #表示处理程序任务列表的开头
    - name: restart apache           #被任务调用的处理程序名称
      service:                       #处理该程序的模块
        name: httpd
        state: restarted
    - name: restart apache
      service:
        name: httpd
        state: restarted              

使用处理程序要注意:

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

2. 忽略任务失败

关键字ignore_errors
通常 playbook 遇到错误会中止执行,但是有时我们想要失败时也继续执行。此时可以使用关键字ignore_errors忽略任务失败。
示例: 当要安装一个系统中不存在的软件包时,忽略任务失败

- name: Latest version of notapkg is installed
  yum:
    name: noaaaaabbbbbbcccccc
    state: latest
  ignore_errors: yes

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

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

[root@localhost ansible]# cat AAAA.yml 
---
- hosts: APP
  force_handlers: yes
  tasks:
    - name: always notify
      command: /bin/true
      notify: restart apache
    - name: fail task
      yum:
        name: noaaaabbbbbbcccc
        state: latest
  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted

尽管任务失败,还是会去执行

[root@localhost ansible]# ansible-playbook -i inventory -i inventory AAAA.yml

PLAY [APP] ***************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.163.134]

TASK [always notify] *****************************************************************************************************************
changed: [192.168.163.134]

TASK [fail task] *********************************************************************************************************************
fatal: [192.168.163.134]: FAILED! => {"changed": false, "failures": ["No package noaaaabbbbbbcccc available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}

RUNNING HANDLER [restart apache] *****************************************************************************************************
changed: [192.168.163.134]

PLAY RECAP ***************************************************************************************************************************
192.168.163.134            : ok=3    changed=2    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0 

4. 指定任务失败条件

关键字:failed_when
fail 模块可以实现此效果,fail 模块可以提供明确消息

tasks:
  - name: Run Script
    shell: /usr/local/bin/user.sh
    register: command_result
    failed_when: "'failure' in command_result.stdout"
#############################使用fail 模块##############################
tasks:
  - name: Run Script
    shell: /usr/local/bin/user.sh
    register: command_result
    ignore_error: yes
  - name: Report failure
    fail:
      msg: "Authentication failure" #fail 模块可以提供明确消息
    when: "'failure' in command_result.stdout"

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

关键字:changed_when:false
简单示例:当执行date命令时,每次都会改变而触发触发器生成changed报告,不想要changed报告就可以添加关键字

- name: get time
  shell: date
  changed_when: false

6.ansible块和错误处理

可以直接可以添加忽略关键字:ignore_errors: yes
也可以使用 block、rescue、always 将任务分开

  1. 三种关键字
    (1)block:定义要运行的主要任务
    (2)rescue:定义要在 block 子句中定义的任务失败时运行的任务
    (3)always:定义始终独立运行的任
---
- name: Task Failure
  hosts: web
  vars:
    web_pkg: http				#此时错误仍然存在
    db_pkg: mariadb-server
    db_service: mariadb
  tasks:
    - name: Set up Web
      block:					#主要任务
        - name: Install {{ web_pkg }} packages
          yum:
            name: "{{ web_pkg }}"
            state: present
      rescue:					#在block子句中定义的任务失败时运行的任务
        - name: Install {{ db_pkg }} packages
          yum:
            name: "{{ db_pkg }}"
            state: present
      always:					#始终运行的任务
        - name: Start {{ db_service }} service
          service:
            name: "{{ db_service }}"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值