ansible实施处理程序、处理任务失败、文件管理
1. 有条件地运行任务
1.1 条件任务的语法
1.1.1 when语句用于有条件地运行任务。
它取要测试的条件为值。如果条件满足。则运行任务。如果条件不满足则跳过任务。
示例:
当when的值为false时就会跳过任务执行,当值为true时就执行。
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [vsftpd] ******************************************************************
skipping: [node2]
PLAY RECAP *********************************************************************
node2 : ok=1 changed=0 unreachable=0 failed=0
[root@node1 ansible]# cat test.yml
---
- hosts: node2
tasks:
- name: vsftpd
yum:
name: vsftpd
state: present
when: false
示例:
// 你也可以设置一个变量来充当true和false
[root@node1 ansible]# cat test.yml
---
- hosts: node2
vars:
install: true
tasks:
- name: install httpd
yum:
name: httpd
state: present
when: install
[root@node2 ~]# rpm -qa | grep httpd
[root@node2 ~]#
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [install httpd] ***********************************************************
changed: [node2]
PLAY RECAP *********************************************************************
node2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node2 ~]# rpm -qa | grep httpd
httpd-filesystem-2.4.37-21.module+el8.2.0+5008+cca404a3.noarch
httpd-2.4.37-21.module+el8.2.0+5008+cca404a3.x86_64
httpd-tools-2.4.37-21.module+el8.2.0+5008+cca404a3.x86_64
redhat-logos-httpd-81.1-1.el8.noarch
示例:
// 当变量未定义一个变量时,用when这个语句去判断一个不存在的变量即为空值,这个时候就会跳过且不会报错
[root@node1 ansible]# cat test.yml
---
- hosts: node2
vars:
tasks:
- name: install httpd
yum:
name: "{{ install }}"
state: present
when: install is defined
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [install httpd] ***********************************************************
skipping: [node2]
PLAY RECAP *********************************************************************
node2 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
2 条件判断符
判断符 | 示例 |
---|---|
等于(值为字符串) | A = “B” |
等于(值为数字) | A = B |
小于 | < |
大于 | > |
小于等于 | <= |
大于等于 | >= |
不等于 | != |
变量存在 | xxx is defined |
变量不存在 | xxx is not defined |
布尔值是true | 1、true yes |
布尔值为false | 0、false no |
第一个变量的值存在,且在第二个变量的列表中 | A in B |
多个条件可以使用
or | 两个条件一个为真即可 |
---|---|
and | 需要两个都为真才可以 |
示例:
// 这是通过操作系统来系统的执行的
如果ansible_facts['distribution']的值在version列表中,则执行此任务,若不在则跳过。
[root@node1 ansible]# cat test.yml
---
- hosts: node3
vars:
version:
- redHat
- CentOS
tasks:
- name: install httpd
yum:
name: httpd
state: present
when: ansible_facts['distribution'] in version
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [install httpd] ***********************************************************
skipping: [node3]
PLAY RECAP *********************************************************************
node3 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
[root@node1 ansible]# cat test.yml
---
- hosts: node3
vars:
version:
- RedHat
- CentOS
tasks:
- name: install httpd
yum:
name: httpd
state: present
when: ansible_facts['distribution'] in version
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [install httpd] ***********************************************************
skipping: [node3]
PLAY RECAP *********************************************************************
node3 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
2.1 多条件测试
条件的意思是当系统为Redhat时,且版本为8就执行任务;只要前面的条件中有一个不成立就执行or后面的条件。
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: install httpd
yum:
name: httpd
state: present
when: >
(ansible_distribution == "RedHat" and
ansible_distribution_major_version == "8")
or
(ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7")
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [install httpd] ***********************************************************
skipping: [node3]
PLAY RECAP *********************************************************************
node3 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
[root@node1 ansible]# cat /etc/redhat-release
Red Hat Enterprise Linux release 8.2 (Ootpa)
因为我这里时Redhat8.2版本所以就执行任务。
2.2 组合循环和有条件任务
// 判断挂载文件系统是否具有超过5000的可用空间,ansible_mounts事实,代表一个已挂载文件系统的相关事实,只要在/下挂载文件满足5000的可以空间即可执行任务
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [install httpd] ***********************************************************
ok: [node3] => (item={'mount': '/', 'device': '/dev/mapper/rhel-root', 'fstype': 'xfs', 'options': 'rw,relatime,attr2,inode64,noquota', 'size_total': 18238930944, 'size_available': 15579222016, 'block_size': 4096, 'block_total': 4452864, 'block_available': 3803521, 'block_used': 649343, 'inode_total': 8910848, 'inode_available': 8848991, 'inode_used': 61857, 'uuid': 'b9c7a6c6-5708-4cb2-a9f5-b2d13417b480'})
skipping: [node3] => (item={'mount': '/mnt/cdrom', 'device': '/dev/sr0', 'fstype': 'iso9660', 'options': 'ro,relatime,nojoliet,check=s,map=n,blocksize=2048', 'size_total': 8436285440, 'size_available': 0, 'block_size': 2048, 'block_total': 4119280, 'block_available': 0, 'block_used': 4119280, 'inode_total': 0, 'inode_available': 0, 'inode_used': 0, 'uuid': '2020-04-04-08-21-15-00'})
skipping: [node3] => (item={'mount': '/boot', 'device': '/dev/sda1', 'fstype': 'xfs', 'options': 'rw,relatime,attr2,inode64,noquota', 'size_total': 1063256064, 'size_available': 876179456, 'block_size': 4096, 'block_total': 259584, 'block_available': 213911, 'block_used': 45673, 'inode_total': 524288, 'inode_available': 523987, 'inode_used': 301, 'uuid': '94b52148-4654-4714-b7f4-4b3aedec9dde'})
- hosts: node3
tasks:
- name: install httpd
command: /usr/bin/systemctl is-active vsftpd //判断vsftpd是否在运行
ignore_errors: yes //若任务失败,则忽略错误继续执行
register: result //将模块的结果信息保存在名为result的变量中
- name:
service:
name: httpd
state: restarted
when: result['rc'] == 0 //评估vsftpd任务的输出。如果systemctl命令的退出代码为0,则vsftpd激活并且此任务重启httpd
3. 实施处理程序
只有使用notify通知时,且修改了配置文件才会执行handlers里面的任务。即使一个任务通知了多次,但是handlers里面的任务只会执行一次,notify必须和handlers组合使用
// 只有当你修改了服务的配置文件才会去执行handlers里面的内容
---
- hosts: node3
tasks:
- name: install httpd
yum:
name: httpd
state: present
notify:
- started httpd
handlers:
- name: start httpd
service:
name: httpd
state: started
3.1 处理任务失败
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: install httpd
yum:
name: httpdd
state: present
ignore_errors: yes //忽略错误当出现错误时跳过,执行后面的任务。
notify:
- started httpd
handlers:
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [install httpd] ***********************************************************
fatal: [node3]: FAILED! => {"changed": false, "failures": ["No package httpdd available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
3.2 任务失败后强制执行处理程序
// 前面的yum安装了一个不存在的服务,按照正常处理的机制会报错退出,但是加了 force_handlers 也会去调用通知去执行handlers里面的任务。
[root@node1 ansible]# cat test.yml
---
- hosts: node3
force_handlers: yes
tasks:
- name: test
command: /bin/true
notify: restart the database
- name: test2
yum:
name: notapkg
state: latest
handlers:
- name: start httpd
service:
name: mariadb
state: restarted
3.3 指定任务失败条件
// 只要输出的结果中有world,就认为任务执行失败了。
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [test] ********************************************************************
changed: [node2]
TASK [fail] ********************************************************************
fatal: [node2]: FAILED! => {"changed": false, "msg": "失败"}
PLAY RECAP *********************************************************************
node2 : ok=2 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
3.4 指定何时报告changed结果
// 不管执行的任务是否再受管主机上进行过修改都是输出changed,如果changed_when: false的话不管修没修改都不输出changed都只显示ok.
---
- hosts: node3
force_handlers: yes
tasks:
- name: test
yum:
name: httpd
state: present
changed_when: true
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [test] ********************************************************************
changed: [node3]
PLAY RECAP *********************************************************************
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [test] ********************************************************************
ok: [node3]
PLAY RECAP *********************************************************************
node3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
当修改为false时就只会显示ok
5 changed与notify组合使用
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
shell: /usr/local/bin/upgrade-database
register: command_result
changed_when: "'Success' in command_result.stdout"
notify:
- restarted mariadb
handlers:
- name:
service:
name: mariadb
state: restarted
#6. Ansible块和错误处理
// block里面可以有多个任务,多个任务组成一个任务块,当其中一个任务执行失败,就任务整个任务块失败就会去执行rescue里面的任务,若block里面的任务执行成功了则就不会执行rescue里面的任务。 always就是不管其他的任务是否执行失败, always里面的任务都会执行。
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
block:
- name: one
yum:
name: httpd
state: present
rescue:
- name: two
service:
name: httpd
state: started
always:
- name: therr
shell: echo 'hello' > /mnt/hgfs/test
模块 | 作用 |
---|---|
block | 定义主要的任务 |
rescue | 定义要在block子句中定义的任务失败时运行的任务 |
always | 定义始终都独立运行的任务,不论block和rescue子句中定义的任务是成功还是失败 |
7. 文件管理
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
blockinfile:
path: /mnt/hgfs/test
block: linux
将test文件里面的内容全部替换掉
7.1copy模块
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [test] ********************************************************************
changed: [node3]
PLAY RECAP *********************************************************************
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
copy:
src: /etc/ansible/passwd
dest: /mnt/hgfs
[root@node3 hgfs]# ls
m.sh passwd test
7.2fetch模块的使用
// 将远程主机上的m.sh这个文件copy到控制节点上的执行位置文件以主机名的组织的文件树中
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
fetch:
src: /mnt/hgfs/m.sh
dest: /etc/ansible/
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [test] ********************************************************************
changed: [node3]
PLAY RECAP *********************************************************************
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
7.3 stat模块的使用
// 查看指定文件的状态信息
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
stat:
path: /etc/ansible/m.sh
// 若想看到输出的结果,需要将结果注册为一个变量,用debug模块将其输出。
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
stat:
path: /etc/ansible/m.sh
register: result
- debug:
var: result
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [test] ********************************************************************
ok: [node3]
TASK [debug] *******************************************************************
ok: [node3] => {
"result": {
"changed": false,
"failed": false,
"stat": {
"exists": false
7.4 synchronize模块的使用
###synchronize是用来同步目录的可以将主控端的目录同步到被控端。
[root@node1 ansible]# ansible-playbook test.yml
PLAY [node3] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node3]
TASK [test] ********************************************************************
ok: [node3]
TASK [同步目录] ********************************************************************
changed: [node3]
PLAY RECAP *********************************************************************
node3 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node1 ansible]# cat test.yml
---
- hosts: node3
tasks:
- name: test
yum:
name: rsync
state: present
- name: 同步目录
synchronize:
src: roles
dest: /opt
[root@node3 opt]# ls
[root@node3 opt]#
[root@node3 opt]# ls
roles