自动化运维—playbook(循环)
文章目录
playbook1
playbook中的循环:
首先还原清单设置:
获取test分组中的主机:
ansible testB -m debug -a "msg={{groups.test}}"
我们发现这里有3台主机被返回,那么如果我们想要看其中一条或者一条一条看呢?
ansible testB -m debug -a "msg={{groups.test[1]}}"
的确可以使用这种索引的方式,但如果我们不知道有多少台主机呢?这时候就需要使用playbook中的循环功能
vim xh1.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_items: "{{groups.test}}"
说明:gather_facts: no表示禁止采集主机信息;
此时我们发现msg后引用了item变量,但我们并没有定义这个变量:with_items会把返回的列表信息自动处理,单独放在一个名为item的变量中,当我们获取到名为item变量的变量值时就可以获取到信息
这样就一条一条循化的把信息输出了
playbook2
如果我们不想从返回的信息列表中循化,而想要循环自己定义的列表,可以使用以下方式:
vim xh2.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_items:
- a
- b
- c
可以看到a,b,c逐条输出
写法2:
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_items: [ a, b, c ]
playbook3
从定义的列表中取指定的对应值输出(有点像字典中的键值对):
vim xh3.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item.test1}}"
with_items:
- { test1: a, test2: b }
- { test1: c, test2: d }
这里可以看到分别取了test1对应的值输出
playbook4
通过上面的例子,我们如何运用循环的知识在远程主机中创建1,2,3,4,四个文件呢?
vim xh4.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- file:
path: "{{item}}"
state: touch
with_items:
- "/opt/1"
- "/opt/2"
- "/opt/3"
- "/opt/4"
可以看到1,2,3,4四个文件都成功创建
写法2:我们还可以将列表的内容写在变量中,引用变量
vim xh4.yml
---
- hosts: testB
remote_user: root
gather_facts: no
vars:
dirs:
- "/opt/1"
- "/opt/2"
- "/opt/3"
- "/opt/4"
tasks:
- file:
path: "{{item}}"
state: touch
with_items: "{{dirs}}"
playbook5
循环结合shell模块,使shell模块循环执行列表中的命令:
vim xh5.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- shell: "{{item}}"
with_items:
- "ls /opt"
- "ls /home"
register: returnvalue
- debug:
var: returnvalue
我们会发现返回的内容太多了,但具体的结果都在results这一部分中,我们可以指定返回results中的内容:
vim xh5.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- shell: "{{item}}"
with_items:
- "ls /opt"
- "ls /home"
register: returnvalue
- debug:
msg: "{{item}}"
with_items: "{{returnvalue.results}}"
还可以指定返回results中的某个信息对应的值:
vim xh5.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- shell: "{{item}}"
with_items:
- "ls /opt"
- "ls /home"
register: returnvalue
- debug:
msg: "{{item.stdout_lines}}"
with_items: "{{returnvalue.results}}"
playbook6
嵌套列表和其他关键字:
之前我们定义的列表都是一个大的列表,那么如果我们定义一个嵌套列表,例如:[[a,b],[1,2,3]]
它又会以怎样的形式输出呢?
vim xh6.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_items:
- [ 1, 2, 3 ]
- [ a, b ]
可以看到它把列表中每个元素单独拿出来了,而不是像我们想要的效果:[a,b] [1,2,3]为两个整体,不拆开
这是因为with_items关键字会把列表中的嵌套列表拉平,如果想要实现不拉平里面列表的效果,需要采用with_list关键字:
vim xh6.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_list:
- [ 1, 2, 3 ]
- [ a, b ]
这次返回的效果就是我们想要的了,其实拉平嵌套列表不只是有with_items关键字,with_flattened关键字和with_items作用很相似
with_together关键字:
vim xh6.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_together:
- [ 1, 2, 3 ]
- [ a, b ]
with_together会将两个小列表中根据索引对应合并起来输出,如果两个列表中值的数量不对应,会自动匹配null
playbook7
如果我们想要在远程主机中的/testdir下分别建立a\b\c三个目录,而三个目录中分别都有1,2,3三个子目录,此时我们可以通过ansible命令:
ansible testB -m shell -a "mkdir -p /testdir/{a,b,c}/{1,2,3}"
但如果我们想要用playbook去实现呢?
首先需要了解一个新的关键字with_cartesian:
vim xh7.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_cartesian:
- [ a, b, c ]
- [ 1, 2, 3 ]
我们发现它不像with_together参数一样把两个列表合并起来输出,而是以排列组合的形式(即a1,a2,a3,b1,b2,b3,c1,c2,c3)
运用这个关键字去实现目录的建立:
vim xh7.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- file:
state: directory
path: /testdir/{{item.0}}/{{item.1}}
with_cartesian:
- [ a, b, c ]
- [ 1, 2, 3 ]
注意:
1.这里的item.0代表第一个小列表中的值,item.1代表第2个小列表中的值
2.与with_cartesian效果相同的关键字是with_nested
playbook8
with_indexed_items关键字,自动添加索引:
vim xh8.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_indexed_items:
- test1
- test2
- test3
可以看到返回时,给他们分别添加了索引
我们可以让它输出成一句话:
vim xh8.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "index is : {{item.0}},value is {{item.1}} "
with_indexed_items:
- test1
- test2
- test3
如果我们给列表中嵌套列表:
vim xh8.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "index is : {{item.0}},value is {{item.1}} "
with_indexed_items:
- [ test1,test2 ]
- [ test3,test4,test5 ]
- [ test6 ]
可以看到它会把嵌套的列表拉平,分别添加索引
如果再嵌套一层列表:
vim xh8.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "index is : {{item.0}},value is {{item.1}} "
with_indexed_items:
- [ test1,test2 ]
- [ [test3,test4],test5 ]
- [ test6 ]
可以看到这一次嵌套的列表没有被拉平,所以说with_indexed_items只会拉平第一次嵌套的列表
playbook9
with_sequence关键字:生成指定数字
vim xh9.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_sequence: start=1 end=5 stride=1
可以看到生成了1-5的数字,start表示开始数字,end表示结束,stride相当于步长
写法2:
vim xh9.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_sequence:
start=1
end=5
stride=2
写法3:如果不指定start end stride参数,直接使用count=5来表示,默认为start=1 end=5 stride=1
vim xh9.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_sequence: count=5
应用:如何利用with_sequence关键字,在远程主机中创建5个分别名为westos2 westos4 westos6 westos8 westos10的五个文件呢?
vim touch.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- file:
path: "/opt/westos{{item}}"
state: touch
with_sequence: start=2 end=10 stride=2
在远程主机中看到文件生成了
playbook10
with_random_choice关键字:随机模块,在列表中随机选定一个数或字符
vim xh10.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_random_choice:
- 1
- 2
- 3
- 4
- 5
可以看到每次返回的结果都不一样,都是从1-5中随机选取的
playbook11
with_dict关键字:字典
vim xh11.yml
---
- hosts: testB
remote_user: root
gather_facts: no
vars:
users:
nigar: female
tom: male
tasks:
- debug:
msg: "{{item}}"
with_dict: "{{users}}"
将user中的信息放入字典中,nigar和tom成为字典的key值,而冒号后面的性别信息成为value值
写法2:根据这一特性,我们可以让输出的内容更加明确
vim xh11.yml
---
- hosts: testB
remote_user: root
gather_facts: no
vars:
users:
nigar: female
tom: male
tasks:
- debug:
msg: "username: {{item.key}},user'gender: {{item.value}}"
with_dict: "{{users}}"
写法3:如果我们再加入一些具体信息,输出时会变成什么样子呢?
vim xh11.yml
---
- hosts: testB
remote_user: root
gather_facts: no
vars:
users:
nigar:
name: Guli nigar
gender: female
telephone: 123-321
tom:
name: Tom Banana
gender: male
telephone: 222-444
tasks:
- debug:
msg: "{{item}}"
with_dict: "{{users}}"
此时我们可以看到,它的key值还是nigar和tom,但value值中多了一些信息
写法4:我们可以从value中再取出具体的值,让输出的内容更加明确
vim xh11.yml
---
- hosts: testB
remote_user: root
gather_facts: no
vars:
users:
nigar:
name: Guli nigar
gender: female
telephone: 123-321
tom:
name: Tom Banana
gender: male
telephone: 222-444
tasks:
- debug:
msg: "user {{item.key}} is {{item.value.name}},gender: {{item.value.gender}},tel: {{item.value.telephone}}"
with_dict: "{{users}}"
playbook12
with_subelements关键字:列表
vim xh12.yml
---
- hosts: testB
remote_user: root
gather_facts: no
vars:
users:
- name: nigar
gender: female
hobby:
- dancing
- rap
- name: tom
gender: male
hobby:
- music
tasks:
- debug:
msg: "{{item}}"
with_subelements:
- "{{users}}"
- hobby
我们可以看到这和playbook11的区别不仅仅在于关键字,在定义变量时将nigar和tom分成了两个部分
执行结果将name和gender作为一个整体,加上nigar的一个爱好dancing输出,再将name和gender作为一个整体,加上nigar的一个爱好rap输出,说明hobby是这个列表中嵌套的一个列表
写法2:我们可以将这两个列表中的指定值拿出来输出
vim xh12.yml
---
- hosts: testB
remote_user: root
gather_facts: no
vars:
users:
- name: nigar
gender: female
hobby:
- dancing
- rap
- name: tom
gender: male
hobby:
- music
tasks:
- debug:
msg: "{{item.0.name}} 's hobby is {{item.1}}"
with_subelements:
- "{{users}}"
- hobby
playbook13
with_file关键字:查看本地ansible主机的文件内容
vim xh13.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_file:
- /testdir/aaa
- /opt/bbb
此时我们看到它返回的信息的确是本地主机中指定文件的信息,说明这与指定的操作主机无关
with_fileglob关键字:查看指定目录下的文件:
vim xh13.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_fileglob:
- /testdir/*
注意:
1.这里查看的是文件名而不是文件内容
2.只能看到文件而不能看目录
写法2:使用通配
vim xh13.yml
---
- hosts: testB
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_fileglob:
- /testdir/*
- /opt/test*.??