ansible-playbook之循环(Loops)

简介:

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
相关文章
LXJ
|
安全 网络安全 数据安全/隐私保护
02-第一条Ansible命令
02-第一条Ansible命令
LXJ
202 0
Ansible playbook忽略错误继续执行
通常情况下, 当出现失败时 Ansible 会停止在宿主机上执行.有时候,你会想要继续执行下去.为此 你需要像这样编写任务: name: this will not be counted as a failure command: /bin/fals...
2979 0
|
应用服务中间件 nginx Python
Ansible-playbook loops循环with_items(学习笔记二十一)
文件 [root@ansible-server ansible]# tree ./ ./ ├── hosts └── loops.yaml hosts 文件 [web] 192.
1294 0
|
Linux 开发工具 Python
Ansible-playbook 条件判断when、pause(学习笔记二十三)
有一些模块,例如copy这个模块有一些机制能跳过本次模块的运行.其实我们也可以使用自己的条件语句去配置跳过模块,这样方便你服务能够选择使用不同的包管理(apt,yum)和不同的文件系统.
1687 0
|
Shell
Ansible 命令执行模块(学习笔记九)
命令执行模块有四个:command、raw、shell、script command、raw 1、command为系统默认模块,使用时可以直接省略: ansible all -a "pwd" image.
1188 0
|
关系型数据库 MySQL Shell