任务实施控制

条件判断

有条件地运行任务

Ansible可使用conditionals在符合特定条件时执行任务或play。
所以我们可以利用条件来区分不同的受管主机,并根据它们所符合的条件来分配功能角色。Playbook变量、注册的变量和Ansible事实都可通过条件来进行测试。可以使用比较字符串、数字数据和布尔值的运算符。

以下场景说明了在Ansible中使用条件的几种情况:

可以在变量中定义硬限制(如min_memory)并将它与受管主机上的可用内存进行比较。
Ansible可以捕获并评估命令的输出,以确定某一任务在执行进一步操作前是否已经完成。例如,如果某一程序失败,则将路过批处理。
可以利用Ansible事实来确定受管主机网络配置,并决定要发送的模板文件(如,网络绑定或中继)。
可以评估CPU的数量,来确定如何正确调节某一Web服务器。
将注册的变量与预定义的变量进行比较,以确定服务是否已更改。例如,测试服务配置文件的MD5检验以和查看服务是否已更改。

条件任务语法

when语句用于有条件地运行任务。它取要测试的条件为值。如果条件满足,则运行任务。如果条件不满足,则跳过任务。

测试my_service变量是否具有值。

---
- hosts: all
  vars: 
    my_ser: httpd
  tasks:
    - name: "{{ my_ser }} package is install" 
      yum: 
        name: "{{ my_ser }}"
        state: present
      when: my_ser is defined

下表显示了在处理条件时可使用的一些运算

项目Value
操作示例
等于(值为字符串)ansible_machine == “x86_64”
等于(值为数字)max_memory == 512
小于min_memory < 128
大于min_memory > 256
小于等于min_memory <= 256
大于等于min_memory >= 512
变量存在min_memory is defined
变量不存在min_memory is not defined
布尔变量是True。1、True或yes的求值为Truememory_available
布尔变量是False 。0、False或no的求值为Falsenot memory_available
第一个变量的值存在,作为第二个变量的列表中的值ansible_distribution in supported_distros

如果ansible_distribution的值在sup_dir列表中,则条件通过且任务运行

---
- hosts: all
  vars:
    sup_dir:
      - RedHat
      - CentOS
  tasks:
    - name: asdad
      yum:
        name: httpd
        state: present
      when: ansible_facts['distribution'] in sup_dir


[root@ansible jay]# ansible-playbook playbook.yml 

PLAY [all] ***********************************************************************

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

TASK [asdad] *********************************************************************
changed: [192.168.10.129]

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

多个条件一起测试:

一个when语句可用于评估多个条件。使用and和or关键字组合条件,并使用括号分组条件。

如果任一条件为真时满足条件语句,则应当使用or语句。

when: ansible_distribution == "Redhat" or ansible_distribution == "CentOS"

使用and运算时,两个条件都必须为真,才能满足整个条件语句。

when: ansible_distribution_version == "7.3" or ansible_distribution == "CentOS"

when关键字还支持使用列表来描述条件列表。向when关键字提供列表时,将使用and运算组合所有条件。

when:
  - ansible_distribution_version == "7.5"
  - ansible_distribution == "CentOS"

通过使用括号分组条件,可以表达更复杂的条件语句。

---
- hosts: all
  tasks:
    - name: asdad
      yum:
        name: httpd
        state: absent
      when: >
        ansible_distribution == "CentOS"
        or
        ansible_distribution_version == "7.5"

组合循环和有条件任务

循环和条件可以组合使用

---
- hosts: all
  tasks:
    - name: asdad
      yum:
        name: httpd
        state: present
      loop: "{{ ansible_facts['mounts'] }}"
      when: 
        - item.mount == "/"
        - item.size_available > 30000000

handlers

简介
需要出发的才能执行任务,当前面的tasks中的任务执行成功后,若希望在此基础上触发其他任务,这时就需要定义handlers。
例如,当通过ansible的模块对目标主机的配置文件进行修改之后,如果任务执行成功,可以触发一个触发器,在触发器中定义目标主机的服务重启操作,以便配置文件生效

特点
handlers是ansible提供的条件机制之一,handlers和tasks很类似,但是只在被tasks通知的时候才会触发执行;
handlers只会在任务执行完成后执行。即使被通知了很多次,也只会执行一次。

playbook

# cat handlers_sample.yaml 
---
- hosts: 127.0.0.1
  handlers:
    - name: echo handlers
      shell: echo "handlers"

  tasks:
    - name: 输出 test1
      shell: echo "test1"

      notify:
        - echo handlers

    - name: 输出test2
      shell: echo "test2"

    - name: 输出test3
      shell: echo "test3"
# 

运行结果

# ansible-playbook -v handlers_sample.yaml 
Using /etc/ansible/ansible.cfg as config file

PLAY [127.0.0.1] ***************************************************************************************************************************************************************************

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

TASK [输出 test1] ****************************************************************************************************************************************************************************
changed: [127.0.0.1] => {"changed": true, "cmd": "echo \"test1\"", "delta": "0:00:00.002695", "end": "2019-05-25 02:22:36.625148", "rc": 0, "start": "2019-05-25 02:22:36.622453", "stderr": "", "stderr_lines": [], "stdout": "test1", "stdout_lines": ["test1"]}

TASK [输出test2] *****************************************************************************************************************************************************************************
changed: [127.0.0.1] => {"changed": true, "cmd": "echo \"test2\"", "delta": "0:00:00.002935", "end": "2019-05-25 02:22:36.898646", "rc": 0, "start": "2019-05-25 02:22:36.895711", "stderr": "", "stderr_lines": [], "stdout": "test2", "stdout_lines": ["test2"]}

TASK [输出test3] *****************************************************************************************************************************************************************************
changed: [127.0.0.1] => {"changed": true, "cmd": "echo \"test3\"", "delta": "0:00:00.002666", "end": "2019-05-25 02:22:37.141926", "rc": 0, "start": "2019-05-25 02:22:37.139260", "stderr": "", "stderr_lines": [], "stdout": "test3", "stdout_lines": ["test3"]}

RUNNING HANDLER [echo handlers] ************************************************************************************************************************************************************
changed: [127.0.0.1] => {"changed": true, "cmd": "echo \"handlers\"", "delta": "0:00:00.002762", "end": "2019-05-25 02:22:37.401675", "rc": 0, "start": "2019-05-25 02:22:37.398913", "stderr": "", "stderr_lines": [], "stdout": "handlers", "stdout_lines": ["handlers"]}

PLAY RECAP *********************************************************************************************************************************************************************************
127.0.0.1                  : ok=5    changed=4    unreachable=0    failed=0   

# 

任务失败处理

任务失败控制

Ansible 通常默认会确保检测模块和命令的返回码并且会快速失败 – 专注于一个错误除非你另作打算.

有时一条命令会返回 0 但那不是报错.有时命令不会总是报告它 ‘改变’ 了远程系统.本章节描述了 如何将 Ansible 处理输出结果和错误处理的默认行为改变成你想要的.

忽略错误的命令

通常情况下, 当出现失败时 Ansible 会停止在宿主机上执行.有时候,会想要继续执行下去.为此需要像这样编写任务

- name: cat no exist file
  command: cat /root/noexist
  ignore_errors: yes
- name: cat file info
 
  shell: cat /root/fileinfo

控制对失败的定义

假设一条命令的错误码毫无意义只有它的输出结果能告诉你什么出了问题,比如说字符串 “FAILED” 出 现在输出结果中.

在 Ansible 1.4及之后的版本中提供了如下的方式来指定这样的特殊行为

- name: this command prints FAILED when it fails
command: /usr/bin/ls  -x -y -z
register: command_result
failed_when: "'FAILED' in command_result.stderr"

在 Ansible 1.4 之前的版本能通过如下方式完成

- name: this command prints FAILED when it fails
  command: /usr/bin/ls -x -y -z
  register: command_result
  ignore_errors: True
  
- name: fail the play if the previous command did not succeed
  fail: msg="the command failed"
  when: "'FAILED' in command_result.stderr"

文件管理

文件模块简介

项目Value
模块名称模块说明
blockinfile插入更新或删除多行文本块
copy复制文件从src到dest,可以设置SELinux属性
fetch与copy相反,用于从被管理主机拉取文件到控制节点,并存储在按住机组名称组织的文件树中
file创建或删除文件、设置权限、链接、设置时间戳等
lineinfile确保某行在文件中,也可以使用正则表达式来替换当前行
stat检索文件的状态信息

file

作用:如果文件存在,就修改文件的时间;如果文件不存在,就创建
可以指定所属组、所属人、设置权限

    - name: User file test
      file:
          path: /home/student/inventory
          owner: student
          group: student
          mode: 0640
          state: touch

删除文件
设置state: absent

---
- name:
  hosts: all
  remote_user: devops
  tasks:
    - file:
        path: /home/devops/users.txt
        state: absent

设置SELinux上下文

 - name:
      file:
        path: /home/devops/users.txt
        seuser: _default
        serole: _default
        setype: _default
        selevel: _default
[student@workstation file-manage]$ ansible all -a 'ls -Z' -u devops
servera.lab.example.com | CHANGED | rc=0 >>
unconfined_u:object_r:user_home_t:s0 inventory
unconfined_u:object_r:user_home_t:s0 users.txt

serverb.lab.example.com | CHANGED | rc=0 >>
unconfined_u:object_r:user_home_t:s0 users.txt

copy

copy可以将文件从src复制到dest
其中有一个force属性,默认为yes。即在目标主机的路径下,若当前文件存在,则覆盖。
将force设置为no,则不会覆盖原文件

---
- name: 
  remote_user: root
  hosts: all
  tasks:
    - name: 
      copy:
        src: /home/student/file-manage/files/users.txt
        dest: /home/devops/users.txt
        owner: devops
        group: devops
        mode: u+rw,g-wx,o-rwx
        setype: samba_share_t

copy还支持将字符串输出到指定文件中:将src换为content

      copy:
        content: abcde
        dest: /home/student/1.txt
        force: yes

fetch

从目标主机拉取文件到控制节点

---
- name: use the fetch 
  hosts: all
  remote_user: root
  tasks:
    - name: fetch the logs
      fetch:
        src: /var/log/secure
        dest: secure-backups
        flat: no

运行结果

[student@workstation file-manage]$ tree secure-backups/
secure-backups/
├── servera.lab.example.com
│   └── var
│       └── log
│           └── secure
└── serverb.lab.example.com
    └── var
        └── log
            └── secure

6 directories, 2 files

lineinfile & blockinfile

lineinfile:指定对目标文件某一行的操作
blockinfile:在文件中插入某个文本块

---
- name:
  hosts: all
  remote_user: devops
  tasks:
    - name:
      lineinfile:
        path: /home/devops/users.txt
        line: this line was addes by the lineinfile module
        state: present
---
- name:
  hosts: all
  remote_user: devops
  tasks:
    - blockinfile:
        path: /home/devops/users.txt
        block: |
          this block of taxt consists of two lines
          they hava been added by the blockinfile module
        state: present

运行结果

serverb.lab.example.com | CHANGED | rc=0 >>
this line was addes by the lineinfile module
# BEGIN ANSIBLE MANAGED BLOCK
this block of taxt consists of two lines
they hava been added by the blockinfile module
# END ANSIBLE MANAGED BLOCK

servera.lab.example.com | CHANGED | rc=0 >>
this line was addes by the lineinfile module
# BEGIN ANSIBLE MANAGED BLOCK
this block of taxt consists of two lines
they hava been added by the blockinfile module
# END ANSIBLE MANAGED BLOCK

stat
检索文件的属性、确定文件校验

---
- name: checksum
  hosts: servera
  tasks:
    - name:
      stat:
        path: /etc/passwd
        checksum_algorithm: md5
      register: result
    - name: debug outpiut
      debug:
        msg: "the res is {{ result.stat.checksum }}"

运行结果

TASK [debug outpiut] *****************************************************************************************************************
ok: [servera] => {
    "msg": "the res is aaf177a0da6689efa01585c7602641fd"
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值