ansible-playbook的循环(Loops)
1.标准的Loops:也是最常用的一种循环
例:当需要安装10个软件包时,不用写10次任务,只需要写一次然后进行循环即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#注:已经安装的软件系统即不在安装 [root@nfs-server playbook] # cat yum_list.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: "需要安装的软件清单"
yum: name={{ item }} state=present
with_items:
- lrzsz
- vim
- sysstat
[root@nfs-server playbook] # ansible-playbook yum_list.yml
PLAY [webservers] ************************************************************************************************************************************** TASK [需要安装的软件清单] *************************************************************************************************************************************** changed: [192.168.2.101] => (item=[u 'lrzsz' , u 'vim' , u 'sysstat' ])
changed: [192.168.2.111] => (item=[u 'lrzsz' , u 'vim' , u 'sysstat' ])
PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=1 changed=1 unreachable=0 failed=0 192.168.2.111 : ok=1 changed=1 unreachable=0 failed=0 |
2.字典格式的循环:with_items
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#写法一: [root@nfs-server playbook] # cat dict_list.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: "字典格式的循环"
debug: msg= "name ---->{{ item.name }},age---->{{ item.age }}"
with_items:
- {name: "Liu Zhengwei" ,age: 28}
- {name: "Jia Dongli" ,age: 25}
#写法二: [root@nfs-server playbook] # cat dict_list.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: "字典格式的循环"
debug: msg= "name ---->{{ item.name }},age---->{{ item.age }}"
with_items:
- name: "Liu Zhengwei"
age: 28
- name: "Jia Dongli"
age: 25
#注:以上两种写法效果是一样的 [root@nfs-server playbook] # ansible-playbook dict_list.yml
PLAY [webservers] ************************************************************************************************************************************** TASK [字典格式的循环] ***************************************************************************************************************************************** ok: [192.168.2.101] => (item={u 'age' : 28, u 'name' : u 'Liu Zhengwei' }) => {
"item" : {
"age" : 28,
"name" : "Liu Zhengwei"
},
"msg" : "name ---->Liu Zhengwei,age---->28"
} ok: [192.168.2.101] => (item={u 'age' : 25, u 'name' : u 'Jia Dongli' }) => {
"item" : {
"age" : 25,
"name" : "Jia Dongli"
},
"msg" : "name ---->Jia Dongli,age---->25"
} ok: [192.168.2.111] => (item={u 'age' : 28, u 'name' : u 'Liu Zhengwei' }) => {
"item" : {
"age" : 28,
"name" : "Liu Zhengwei"
},
"msg" : "name ---->Liu Zhengwei,age---->28"
} ok: [192.168.2.111] => (item={u 'age' : 25, u 'name' : u 'Jia Dongli' }) => {
"item" : {
"age" : 25,
"name" : "Jia Dongli"
},
"msg" : "name ---->Jia Dongli,age---->25"
} PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=1 changed=0 unreachable=0 failed=0 192.168.2.111 : ok=1 changed=0 unreachable=0 failed=0 |
3.嵌套Loops(列表格式的循环,用于1对多或者多对多关系时)--> with_nested
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
[root@nfs-server playbook] # cat netsted_list.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: "实现1对多关系的循环"
debug: msg= "name--->{{ item[0] }},value--->{{ item[1] }}"
with_nested:
- [ 'A' ]
- [ 'a' , 'b' , 'c' ]
[root@nfs-server playbook] # ansible-playbook netsted_list.yml -l 192.168.2.101
PLAY [webservers] ************************************************************************************************************************************** TASK [实现1对多关系的循环] ************************************************************************************************************************************** ok: [192.168.2.101] => (item=[u 'A' , u 'a' ]) => {
"item" : [
"A" ,
"a"
],
"msg" : "name--->A,value--->a"
} ok: [192.168.2.101] => (item=[u 'A' , u 'b' ]) => {
"item" : [
"A" ,
"b"
],
"msg" : "name--->A,value--->b"
} ok: [192.168.2.101] => (item=[u 'A' , u 'c' ]) => {
"item" : [
"A" ,
"c"
],
"msg" : "name--->A,value--->c"
} PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=1 changed=0 unreachable=0 failed=0 |
4.散列loops:with_dict(支持更丰富的数据结构)
注:with_dict的写法在新版本中进行了改变,必须要写成字典的形式,跟我下面写的格式一样
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
[root@nfs-server playbook] # cat with_dict.yml
--- - hosts: webservers gather_facts: False
remote_user: root
vars:
user:
shencan:
name: shencan
shell: bash
ruifengyun:
name: ruifengyun
shell: zsh
tasks:
- name: debug loops
debug: "msg=name--->{{ item.key }} value--->{{ item.value.name }} shell--->{{ item.value.shell }}"
with_dict: "{{ user }}"
[root@nfs-server playbook] # ansible-playbook with_dict.yml -l 192.168.2.101
PLAY [webservers] ************************************************************************************************************************************** TASK [debug loops] ************************************************************************************************************************************* ok: [192.168.2.101] => (item={ 'key' : u 'ruifengyun' , 'value' : {u 'shell' : u 'zsh' , u 'name' : u 'ruifengyun' }}) => {
"item" : {
"key" : "ruifengyun" ,
"value" : {
"name" : "ruifengyun" ,
"shell" : "zsh"
}
},
"msg" : "name--->ruifengyun"
} ok: [192.168.2.101] => (item={ 'key' : u 'shencan' , 'value' : {u 'shell' : u 'bash' , u 'name' : u 'shencan' }}) => {
"item" : {
"key" : "shencan" ,
"value" : {
"name" : "shencan" ,
"shell" : "bash"
}
},
"msg" : "name--->shencan"
} PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=1 changed=0 unreachable=0 failed=0 |
5.文件匹配loops:with_fileglob
在工作中,我们经常遇到需要针对一个目录下指定格式的文件进行处理,这个时候直接引用with_fileglob循环去匹配我们需要处理的文件即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
[root@nfs-server playbook] # cat with_fileglob.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: debug loops
debug: "msg=files-->{{ item }}"
with_fileglob:
- /var/log/nginx/ *.gz
[root@nfs-server playbook] # ansible-playbook with_fileglob.yml
PLAY [webservers] ************************************************************************************************************************************** TASK [debug loops] ************************************************************************************************************************************* ok: [192.168.2.101] => (item= /var/log/nginx/host .access.log-20170816.gz) => {
"item" : "/var/log/nginx/host.access.log-20170816.gz" ,
"msg" : "files-->/var/log/nginx/host.access.log-20170816.gz"
} ok: [192.168.2.101] => (item= /var/log/nginx/error .log-20170815.gz) => {
"item" : "/var/log/nginx/error.log-20170815.gz" ,
"msg" : "files-->/var/log/nginx/error.log-20170815.gz"
} ok: [192.168.2.101] => (item= /var/log/nginx/error .log-20170823.gz) => {
"item" : "/var/log/nginx/error.log-20170823.gz" ,
"msg" : "files-->/var/log/nginx/error.log-20170823.gz"
} ok: [192.168.2.111] => (item= /var/log/nginx/access .log-20170817.gz) => {
"item" : "/var/log/nginx/access.log-20170817.gz" ,
"msg" : "files-->/var/log/nginx/access.log-20170817.gz"
} ok: [192.168.2.111] => (item= /var/log/nginx/error .log-20170825.gz) => {
"item" : "/var/log/nginx/error.log-20170825.gz" ,
"msg" : "files-->/var/log/nginx/error.log-20170825.gz"
} PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=1 changed=0 unreachable=0 failed=0 192.168.2.111 : ok=1 changed=0 unreachable=0 failed=0 |
6.随机选择loops:with_random_choice(会从给定的值中随便选取一个显示)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
[root@nfs-server playbook] # cat with_random_choice.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: debug loops
debug: 'msg="name --> {{ item }}"'
with_random_choice:
- "Beijing"
- "Shanghai"
- "TianJin"
[root@nfs-server playbook] # ansible-playbook with_random_choice.yml
PLAY [webservers] ************************************************************************************************************************************** TASK [debug loops] ************************************************************************************************************************************* ok: [192.168.2.101] => (item=Beijing) => { "item" : "Beijing" ,
"msg" : "name --> Beijing"
} ok: [192.168.2.111] => (item=Shanghai) => { "item" : "Shanghai" ,
"msg" : "name --> Shanghai"
} PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=1 changed=0 unreachable=0 failed=0 192.168.2.111 : ok=1 changed=0 unreachable=0 failed=0 |
7.条件判断loops
在某些情况下,我们需要检测某个task是否达到了预想的状态,如果没有达到,就需要退出整个剧本。
until:检测条件
retries:检测次数
delay:每次检测的间隔时长
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
[root@nfs-server playbook] # cat if_else.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: "对task的执行结果进行判断"
shell: cat /etc/fstab
register: info
until : info.stdout.startswith( "sysfs" )
retries: 5
delay: 5
[root@nfs-server playbook] # ansible-playbook if_else.yml
PLAY [webservers] ************************************************************************************************************************************** TASK [对task的执行结果进行判断] ********************************************************************************************************************************** FAILED - RETRYING: 对task的执行结果进行判断 (5 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (5 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (4 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (4 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (3 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (3 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (2 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (2 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (1 retries left). FAILED - RETRYING: 对task的执行结果进行判断 (1 retries left). fatal: [192.168.2.111]: FAILED! => { "attempts" : 5, "changed" : true , "cmd" : "cat /etc/fstab" , "delta" : "0:00:00.003310" , "end" : "2017-09-04 01:09:18.651001" , "failed" : true , "rc" : 0, "start" : "2017-09-04 01:09:18.647691" , "stderr" : "" , "stderr_lines" : [], "stdout" : "\n#\n# /etc/fstab\n# Created by anaconda on Sun Jun 26 03:08:48 2016\n#\n# Accessible filesystems, by reference, are maintained under '/dev/disk'\n# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info\n#\n/dev/mapper/vg_test2-lv_root / ext4 defaults 1 1\nUUID=8699d6c2-883b-41a0-8282-5be27641ee02 /boot ext4 defaults 1 2\n/dev/mapper/vg_test2-lv_swap swap swap defaults 0 0\ntmpfs /dev/shm tmpfs defaults 0 0\ndevpts /dev/pts devpts gid=5,mode=620 0 0\nsysfs /sys sysfs defaults 0 0\nproc /proc proc defaults 0 0\n/dev/cdrom /media/cdrom iso9660 defaults 0 0" , "stdout_lines" : [ "" , "#" , "# /etc/fstab" , "# Created by anaconda on Sun Jun 26 03:08:48 2016" , "#" , "# Accessible filesystems, by reference, are maintained under '/dev/disk'" , "# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info" , "#" , "/dev/mapper/vg_test2-lv_root / ext4 defaults 1 1" , "UUID=8699d6c2-883b-41a0-8282-5be27641ee02 /boot ext4 defaults 1 2" , "/dev/mapper/vg_test2-lv_swap swap swap defaults 0 0" , "tmpfs /dev/shm tmpfs defaults 0 0" , "devpts /dev/pts devpts gid=5,mode=620 0 0" , "sysfs /sys sysfs defaults 0 0" , "proc /proc proc defaults 0 0" , "/dev/cdrom /media/cdrom iso9660 defaults 0 0" ]}
fatal: [192.168.2.101]: FAILED! => { "attempts" : 5, "changed" : true , "cmd" : "cat /etc/fstab" , "delta" : "0:00:00.002489" , "end" : "2017-09-04 01:11:02.560507" , "failed" : true , "rc" : 0, "start" : "2017-09-04 01:11:02.558018" , "stderr" : "" , "stderr_lines" : [], "stdout" : "\n#\n# /etc/fstab\n# Created by anaconda on Sun Jun 26 03:11:47 2016\n#\n# Accessible filesystems, by reference, are maintained under '/dev/disk'\n# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info\n#\n/dev/mapper/vg_test3-lv_root / ext4 defaults 1 1\nUUID=e48217af-0ad9-45be-aa68-b0b1bbc88c97 /boot ext4 defaults 1 2\n/dev/mapper/vg_test3-lv_swap swap swap defaults 0 0\ntmpfs /dev/shm tmpfs defaults 0 0\ndevpts /dev/pts devpts gid=5,mode=620 0 0\nsysfs /sys sysfs defaults 0 0\nproc /proc proc defaults 0 0\n/dev/cdrom /media/cdrom iso9660 defaults 0 0" , "stdout_lines" : [ "" , "#" , "# /etc/fstab" , "# Created by anaconda on Sun Jun 26 03:11:47 2016" , "#" , "# Accessible filesystems, by reference, are maintained under '/dev/disk'" , "# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info" , "#" , "/dev/mapper/vg_test3-lv_root / ext4 defaults 1 1" , "UUID=e48217af-0ad9-45be-aa68-b0b1bbc88c97 /boot ext4 defaults 1 2" , "/dev/mapper/vg_test3-lv_swap swap swap defaults 0 0" , "tmpfs /dev/shm tmpfs defaults 0 0" , "devpts /dev/pts devpts gid=5,mode=620 0 0" , "sysfs /sys sysfs defaults 0 0" , "proc /proc proc defaults 0 0" , "/dev/cdrom /media/cdrom iso9660 defaults 0 0" ]}
to retry, use: --limit @ /ansible/playbook/if_else .retry
PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=0 changed=0 unreachable=0 failed=1 192.168.2.111 : ok=0 changed=0 unreachable=0 failed=1 |
8.register同时接收多个变量进行传递
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#注:接收到的多个值可以用jinja的for循环方式显示每个值 [root@nfs-server playbook] # cat register_vars.yml
--- - hosts: webservers remote_user: root
gather_facts: False
tasks:
- name: "register接受多个值测试"
shell: "{{ item }}"
with_items:
- hostname
- uname
register: ret
- name: "显示接收到的值"
debug: 'msg="{% for i in ret.results %} {{ i.stdout }} {% endfor%}"'
[root@nfs-server playbook] # ansible-playbook register_vars.yml
PLAY [webservers] ************************************************************************************************************************************** TASK [register接受多个值测试] ********************************************************************************************************************************* changed: [192.168.2.101] => (item= hostname )
changed: [192.168.2.111] => (item= hostname )
changed: [192.168.2.101] => (item= uname )
changed: [192.168.2.111] => (item= uname )
TASK [显示接收到的值] ***************************************************************************************************************************************** ok: [192.168.2.101] => { "msg" : " lamp1 Linux "
} ok: [192.168.2.111] => { "msg" : " lamp2 Linux "
} PLAY RECAP ********************************************************************************************************************************************* 192.168.2.101 : ok=2 changed=1 unreachable=0 failed=0 192.168.2.111 : ok=2 changed=1 unreachable=0 failed=0
本文转自激情燃烧的岁月博客51CTO博客,原文链接http://blog.51cto.com/liuzhengwei521/1962259如需转载请自行联系原作者 weilovepan520 |