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
|