Ansible 中任务执行控制
Posted 123坤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ansible 中任务执行控制相关的知识,希望对你有一定的参考价值。
1. 循环
循环迭代任务
- 简单循环
loop: ##赋值列表
- value1
- value2
- ...
{{item}} ##迭代变量名称
测试:
用迭代循环的方式来建立多个用户,编写剧本内容如下所示:
1 ---
2 - name: test
3 hosts: 172.25.254.100
4 tasks:
5 - name: create user
6 user:
7 name: "{{item}}"
8 state: present
9 loop:
10 - user1
11 - user2
12 - user3
执行过程以及结果如下图所示:
- 循环散列或字典列表
写成字典形式建立用户的剧本如下所示:
1 ---
2 - name: test
3 hosts: 172.25.254.100
4 tasks:
5 - name: create user
6 user:
7 name: "{{item['name']}}"
8 uid: "{{item['uid']}}"
9 state: present
10 loop:
11 - name: lll
12 uid: 11211
13 - name: xxx
14 uid: 22111
15 - name: ggg
16 uid: 33456
执行效果如下图所示:
编写开启服务的剧本如下所示:
---
- name: test
hosts: 172.25.254.100
tasks:
- name: open/off service
service:
name: "{{ item.name}}"
state: "{{ item.state }}"
loop:
- name: httpd
state: started
- name: vsftpd
state: stopped
task:
安装 ftp ,允许匿名用户登陆;创建虚拟用户有 user1 的目录在 /var/virtual/user1,密码为 123; 用户 user2 的目录在 /var/virtual/user2,密码为 456。
编写剧本的如下:
1 ---
2 - name: VSFTPD
3 hosts: 172.25.254.100
4 vars: ##设定变量
5 Virtual_Users:
6 - name: user1
7 home: /var/virtual/user1
8 password: 123
9 - name: user2
10 home: /var/virtual/user2
11 password: 456
12 tasks: ##安装服务
13 - name: install vsftpd
14 dnf:
15 name: vsftpd
16 state: latest
17
18 - name: clear userlistfile ##清理文件内容
19 file:
20 path: "{{item}}"
21 state: absent
22 loop:
23 - /etc/vsftpd/vusers
24 - /etc/pam.d/vusers
25
26 - name: create userlistfile ##创建认证文件
27 lineinfile:
28 path: /etc/vsftpd/vusers
29 line: "{{item.name}}\\n{{item.password}}"
30 create: yes
31 loop:
32 "{{Virtual_Users}}"
33
34 - name: encrpyt userlistfile ##认证文件加密
35 shell: db_load -T -t hash -f /etc/vsftpd/vusers /etc/vsftpd/vusers.db
36
37 - name: create vuser home ##创建虚拟用户的目录
38 file:
39 path: "{{item.home}}"
40 state: directory
41 loop:
42 "{{Virtual_Users}}"
43
44 - name: configure vsftpd ##设定服务的读取规则
45 lineinfile:
46 path: /etc/vsftpd/vsftpd.conf
47 regexp: "{{item.conf_src}}"
48 line: "{{item.conf_dest}}"
49
50 loop:
51 - conf_src: anonymous_enable=NO
52 conf_dest: anonymous_enable=YES
53 - conf_src: pam_service_name=vsftpd
54 conf_dest: "pam_service_name=vuser\\nguest_enable=Yes\\nguest_username=ftp\\nlocal_root=/var/ virtual/$USER\\nuser_sub_token=$USER"
55
56 - name: create pam rule file ##建立认证策略
57 lineinfile:
58 path: /etc/pam.d/vuser
59 line: "{{item}}"
60 create: yes
61 loop:
62 - account required pam_userdb.so db=/etc/vsftpd/vusers
63 - auth required pam_userdb.so db=/etc/vsftpd/vusers
64
65 - name: start vsftpd ##开启服务
66 service:
67 name: vsftpd
68 state: started
69
70 - name: firewalld ##设定火墙
71 firewalld:
72 service: ftp
73 zone: public
74 permanent: yes
75 state: enabled
76 immediate: yes
执行效果如图所示:
2. 条件
- when:
- 条件1
- 条件2
条件判断
符号 | 含义 |
---|---|
= | value == “字符串”,value == 数字,数字不加引号,加上引号之后数字也变为字符串 |
< | value < 数字 |
> | value > 数字 |
<= | value <= 数字 |
>= | value >= 数字 |
!= | value != 数字 |
is defined value ,value is defined | 变量存在 |
is not defined ,value is not defined | 变量不存在 |
in , value is in value | 变量为 |
not in , value is not in value | 变量不为 |
bool变量 为true ,value | value的值为true |
bool变量 false ,not value | value的值为false |
value in value2 | value的值在value2列表中 |
多条条件组合
when:
条件1 and 条件2
- 条件1
- 条件2
when:
条件1 or 条件2
when: >
条件1
or
条件2
如编写一个剧本用来判断某个ip 的主机是否网路通畅,当通畅时提示主机开启;内容如下所示:
1 ---
2 - name: check
3 hosts: 172.25.254.100
4 tasks:
5 - name: ping
6 shell:
7 ping -c1 -w1 172.25.254.200
8 ignore_errors: yes ##忽略错误,不然当 ping 不同时就不会执行下面的动作
9 register: westos ##注册变量
10 - debug: ##当可以 ping 通时
11 msg: host is up
12 when: westos.rc == 0 ##对于判定变量的书写不用加括号
13 - debug: ##当 ping 不通时
14 msg: host is down
15 when: westos.rc != 0
执行效果如图所示:
编写一个剧本来判定受控主机中的设备是否存在,编写剧本如下所示:
1 ---
2 - name: check
3 hosts: 172.25.254.100
4 tasks:
5 - debug:
6 msg: vda is exist
7 when: ansible_facts['devices']['vda'] is defined
8 - debug:
9 msg: vda is not exist
10 when: ansible_facts['devices']['vda'] is not defined
测试结果如下图所示:
编辑剧本如下所示:
1 ---
2 - name: check
3 hosts: westos
4 tasks:
5 - debug:
6 msg: vda is exist
7 when:
8 - ansible_facts['devices']['vda'] is defined
9 - inventory_hostname is in "172.25.254.100"
10 - debug:
11 msg: vda is not exist
12 when:
13 - ansible_facts['devices']['vda'] is not defined
14 - inventory_hostname is in "172.25.254.100" ##当 hostname 为100 时执行
结果如下图所示:
test 建立 playbook ~/ansibles/lvm.yml要求如下:
1)建立大小为1500M名为exam_lvm的 lvm 在 westos 组中;
2)如果 westos 不存在请输出: vg westos is not exist;
3)如果 westos 大小不足1500M请输出: vg westos is less then 1500M;
4) 并建立800M大小的 lvm。
编写剧本内容如下所示:
1 ---
2 - name: create lvm
3 hosts: westos
4 tasks:
5 - name: check vg ##判定是否被设定
6 debug:
7 msg: vg westos is not exist
8 when: ansible_facts['lvm']['vgs']['westos'] is not defined
9
10 - name: create lv ##创建1500M lv
11 lvol:
12 vg: westos
13 lv: exam_lvm
14 size: 1500m
15 when: ansible_facts['lvm']['vgs']['westos'] is defined
16 ignore_errors: yes ##当创建失败时,忽略错误,继续执行
17 register: LAG_LVM
18
19 - debug: ##提示小于1500M
20 msg: vg westos is less then 1500M
21 when: ansible_facts['lvm']['vgs']['westos'] is defined
22
23 - name: create 800 lv ##创建800M lv
24 lvol:
25 vg: westos
26 lv: exam_lvm
27 size: 800m
28 when:
29 - ansible_facts['lvm']['vgs']['westos'] is defined
30 - LAG_LVM.rc != 0
3. 触发器
notify: 触发器当遇到更改时触发handlers
handlers: 触发器触发后执行的动作
如当一个服务的配置文件被更改时,会触发重启服务的动作;
编辑一个 playbook 来观察其效果,如下所示:
1 ---
2 - name: test
3 hosts: westos
4 vars: ##变量值
5 PORT: 80
6 tasks:
7 - name: install apache ##安装服务
8 dnf:
9 name: httpd
10 state: latest
11 - name: config apache ##编辑配置文件
12 lineinfile:
13 path: /etc/httpd/conf/httpd.conf
14 regexp: "^Listen"
15 line: Listen "{{PORT}}"
16 notify: restart apache ##当内容更改之后,将信息传递到 restart apache 所在位置,引起触发器触发接下来的动作。
17
18 - name: start apache
19 service:
20 name: httpd
21 state: started
22
23 handlers: ##当接收的触发信息是,执行接下来的动作。
24 - name: restart apache
25 service:
26 name: httpd
27 state: restarted
此时 80 是 httpd 的默认端口便不会触发触发器执行重启服务的动作;当更该之后此时执行效果下图所示:
4. 处理失败任务
- ignore_errors
作用:
当 play 遇到任务失败是会终止;ignore_errors: yes
将会忽略任务失败使下面的任务继续运行;
如有一个执行错误的playbook 如下所示:
1 ---
2 - name: test
3 hosts: 172.25.254.100
4 tasks:
5 - name: install apache
6 dnf:
7 name: zxk
8 state: present
9
10 - name: touch file
11 file:
12 path: /mnt/zxkfile
13 state: touch
执行效果如下所示:
当加入参数 ignore_errors: yes
之后,便可继续执行后面的动作:
- force_handlers
作用:当任务失败后 play 被终止也会调用触发器进程;
在含有触发器的 play 中,当有错误时会导致触发器也不能生效;如图所示:
当加入参数 force_handlers: yes
之后,此时虽然 play 出错,但是触发器还是会生效;
- changed_when
作用:控制任务在何时报告它已进行更改;
如更改 apache 端口,当不更改端口时,此时是不会触发触发器,加入此参数的目的是为了不管值会不会更改,都报告已经更改或者没有更改;
1 ---
2 - name: test
3 hosts: 172.25.254.100
4 vars:
5 PORT: 80
6 tasks:
7 - name: install apache
8 dnf:
9 name: httpd
10 state: latest
11 - name: config apache
12 lineinfile:
13 path: /etc/httpd/conf/httpd.conf
14 regexp: "^Listen"
15 line: Listen "{{PORT}}"
16 notify: restart apache
17 changed_when: yes
18
19 - name: start apache
20 service:
21 name: httpd
22 state: started
23
24 - name: error
25 dnf:
26 name: zxk
27 state: present
28 ignore_errors: yes
29
30 handlers:
31 - name: restart apache
32 service:
33 name: httpd
34 state: restarted
执行效果如下图所示,虽然没有更改端口信息,但是报告出去的是已经更改了内容,此时会重启服务;
- failed_when
当符合条件时强制任务失败
编写一个 play 来观察实验效果,内容如下所示:
1 ---
2 - name: test
3 hosts: 172.25.254.100
4 tasks:
5 - name: shell
6 shell:
7 echo hello zxk
8 register: KKK
9 ignore_errors: yes
10
11 - name: touch file
12 file:
13 path: /mnt/zxkfile
14 state: touch
执行结果如下所示:
此时没有参数,执行时可以输出,当加入参数 failed_when :yes
表示符合条件时强制任务失败 ;
- block
block: 定义要运行的任务;
rescue: 定义当block句子中出现失败任务后运行的任务;
always: 定义最终独立运行的任务;
如编辑一个 playbook 来观察实验效果,用来创建逻辑卷内容如下所示:
1 ---
2 - name: test
3 hosts: westos
4 tasks:
5 - name: create lvm
6 block: ##定义要运行的任务;
7 - name: create 1500M lv
8 lvol:
9 vg: westos
10 lv: exam_lvm
11 size: 1500m
12 when: ansible_facts['lvm']['vgs']['westos'] is defined
13
14 rescue: ##当block中出现失败任务后运行的任务;
15 - name: create 800M lv
16 lvol:
17 vg: westos
18 lv: exam_lvm
19 size: 800m
20 when: ansible_facts['lvm']['vgs']['westos'] is defined
21
22 always: ##定义最终独立运行的任务;
23 - debug:
24 msg: vg westos is not exist
25 when: ansible_facts['lvm']['vgs']['westos'] is not defined
测试练习 建立 playbook ~/westos.yml要求如下:
1)建立大小为 25G 名为 /dev/vdb1 的设备;
2)如果 /dev/vdb 不存在请输入: /dev/vdb is not exis;
3)如果/dev/vdb大小不足 25G 请输出: /dev/vdb is less then 25G;
4)并建立 10G 大小的 /dev/vdb1;此设备挂载到/westos上。
注:可以用命令 ansible-doc parted | less
来查看创建分区时的帮助信息,用命令 ansible-doc filesystem | less
来查看格式化时的帮助信息;用命令 ansible-doc mount | less
来查看挂载时的帮助信息;
编写剧本内容如下所示:
1 ---
2 - name: test
3 hosts: 172.25.254.100
4 tasks:
5 - name: create device
6 block:
7 - name: create 25G device
8 parted:
9 device: /dev/vdb
10 number: 1
11 state: present
12 part_end: 25GiB
13
14 rescue:
15 - name: create 10G device
16 block:
17 - parted:
18 device: /dev/vdb
19 number: 1
20 state: present
21 part_end: 10GiB
22
23 - debug:
24 msg: /dev/vdb is less then 25G
25
26 rescue:
27 - debug:
28 msg: /dev/vdb is not exist
29
30 always:
31 - name: create filesystem
32 filesystem:
33 fstype: xfs
34 dev: /dev/vdb1
35 when: ansible_facts['devices']['vdb'] is defined
36
37 - name: mount device
38 mount:
39 path: /westos
40 src: /dev/vdb1
41 fstype: xfs
42 opts: defaults
43 state: mounted
44 when: ansible_facts['devices']['vdb'] is defined
测试结果如下所示:
以上是关于Ansible 中任务执行控制的主要内容,如果未能解决你的问题,请参考以下文章
ansible自动化运维详解ansible中的任务执行控制及实例演示:循环条件判断触发器处理失败任务
ansible自动化运维详解ansible中的任务执行控制及实例演示:循环条件判断触发器处理失败任务
ansible自动化运维详解ansible中的任务执行控制及实例演示:循环条件判断触发器处理失败任务