5-playbook拓展
Handlers
首先我们设定以这个场景。
想要将test3主机中/home/test.txt文件中的我们现在学习XXX
修改为我们现在学习ansible
,并打印修改后的结果。
test.txt文本
1 | 1 |
编写的playbook为
1 |
|
可以看出两个任务都执行成功了。
如果要再执行一次该playbook呢。
task1因为文件状态与playbook中的状态是一致的,所以为绿的;但是task2为黄色,虽然也执行成功,最后的状态与我们的设定是一致的,但是相当于白执行了一次。在该例子中对结果或者过程影响不大,但是当我们需要修改某个服务的配置文件并进行重启服务时,就会对想先关的业务造成影响。
handlers可以对这种问题进行解决,简单来说handlers就是另一种tasks,handlers中的任务会被tasks中的任务进行调用。例如task1调用handler1,当task1执行状态为黄色时,handler1才会被执行,当task1执行状态为绿色,即task1没有被真正被执行时,handlers不会被执行。
对上面的palybook进行修改,notify
执指向handlers中的任务(即handlers中任务的name)。
1 |
|
然后我们对/home/test.txt进行还原,然后重新执行playbook。
可以看出task和handler都执行了。
再执行一边。
可以看到只有task被执行了,handler没有被执行。
Handlers进阶
notify
调用多个handler
1 | notify : |
mate模块 (mate:flush_handlers)
1 |
|
默认情况下handler执行的顺序与handler在playbook的handlers模块定义的顺序是相同的,与”handler被notify”的顺序无关。所有task执行完毕后,才会执行各个handler,并不是执行完某个task后,立即执行对应的handler。若要执行完task后马上执行对应handler,则需要使用mate模块。
1 |
|
在testtask1和testtask2之间有一个mate任务,meta任务能够影响ansible内部运行方式,meta : flush_handlers
表示立即执行之前的task所对应handler,mate之前有多个notify调用时,被调用的handler的执行顺序还是与handlers模块的顺序一致。
listen模块
使用listen
对handler进行“分组”,使用notify调用该组时将会调用该组下的成员。
1 |
|
变量
playbook中的变量名以英文大小写字母开头,中间可以包含下划线和数字。
在Inventory文件中以=
来为变量赋值,在playbook或者变量配置文件中以:
来为变量赋值。
playbook变量
运行playbook时指定额外的变量
1
2ansible-playbook test.yml -e "newVar=test" #指定额外的变量
ansible-playbook test.yml -e "@newVar.yml" #指定变量配置文件playbook中定义变量
使用vars
来进行定义变量。1
2
3
4
5
6
7
8
9
10
11
- hosts : test3
vars :
var1 : test1
var2 : test2
#- var1 : test1 这样定义也是可以的
#- var2 : test2
tasks :
- name : 变量测试
debug :
msg : var1={{var1}} var2={{var2}}debug模块的msg参数可以自定义输出;而var参数可以直接输出变量信息,且不需要使用两个括号进行引起
1
2
3
4
5
6
7
8
9
- hosts : test3
vars :
- var1 : test1
tasks :
- name : 变量测试
debug :
var :
var1也可以在playbook中引用变量文件
1
2
3
4
5
6
7
8
9
10#palybook文件
- hosts : test3
vars_files :
- vars.yml
- vars.yml
tasks :
- name : 变量文件测试
debug :
msg : "{{var1}}"1
2
var1 : test在使用
:
的方式引用变量{{var1}}
时,当{{var1}}
处于开头位置需要加上引号,当{{var1}}
前有字符串时则可以不加双引号。
除了使用:
来进行引用变量,还可以使用=
来引用变量,使用=
来引用变量时可以不用考虑加不加双引号。1
2
3
4
5
6
7
8
- hosts : test3
vars :
var1 : test1
tasks :
- name : 变量测试
debug :
msg = {{var1}}在playbook中还可以以类似”属性”的方式定义变量
1
2
3
4
5
6
7
8
9
10
- hosts : test3
vars :
people :
name : xiaoming
age : 20
tasks :
- name : 变量测试
debug :
msg : 名字为{{people.name}},年龄为{{people.age}}
注册变量
注册变量就是将操作的结果,包括标准输出和标准错误输出,保存到变量中。在同一个yml中操作同一台主机时,前一个play定义了register变量,后面的同一台主机中也可以调用到该register变量。
1 |
|
这时就可以使用类似这样的方式引用详细的值
Facts(收集系统信息)
运行playbook之前,ansible默认会先抓取playbook指定的所有主机的系统信息,这些信息就成为facts。
facts信息包含远程主机的CPU、IP、磁盘空间、操作系统信息等等。可以根据这些信息来判断是否进行下一步任务,或者将这些信息写入到某个配置中。
这些信息可以使用setup模块来获取
1 | ansible test3 -m setup |
对于使用不到这些信息的playbook来说收集facts的过程是可以跳过的。
1 |
|
facts变量
定义远程主机的facts变量,需要在远程主机的/etc/ansible/facts.d
目录下创建INI风格的xxx.fact文件。
1 | #/etc/ansible/facts.d/test.fact文件 |
filter=ansible_local
表示将ansible_local(本地facts)从所有facts中过滤出来,也可以使用*local
类似这样的通配符进行匹配。
setup收集的本地fact变量是从/etc/ansible/facts.d目录下的文件中收集,当我们的facts变量文件是在远程主机的其他目录下时,需要指定文件路径
1 | #当facts变量文件是在/tmp目录下 |
通过set_fact定义变量
可以使用set_fact模块在tesk中定义变量。在同一个yml中操作同一台主机时,前一个play定义了set_fact变量,后面的同一台主机中也可以调用到该set_fact变量。
1 |
|
提示用户输入信息并写入到变量
实现交互式输入信息,并将信息
1 |
|
这样在输入值的时候就可以看到输入的确切的值,若是不想显示则将private设置为yes(默认选项)。
内置变量
ansible_version
内置变量ansible_version可以获取到ansible的版本号
1 | ansible test3 -m debug -a "msg={{ansible_version}}" |
hostvars
hostvars可以在操作A主机时获取到B主机的信息。
收集facts信息
1
2
3
4
5
6
7
8
9
- hosts : test4
name : play1 hostsname is test4
- hosts : test3
name : play2 hostsname is test3
tasks :
- debug :
msg : hostvars['test4'].ansible_hostname:{{hostvars['test4'].ansible_hostname}}
play1并没有task,但是这并不代表play1是没有用的,正是运行过play1收集了test4的facts信息,在play2中才可以使用fast4的facts信息。收集注册变量、主机变量、组变量
收集注册变量时,不需要像收集facts信息一样需要事先进行收集,同样的也可以收集在主机清单中配置的主机变量与组变量1
2
3
4
5
6
7
8
9
- hosts : test4
tasks :
- shell : "echo this is test4 "
register : testvar
- hosts : test3
tasks :
- debug :
msg : "{{hostvars.test4.testvar}}"收集定义变量
在play中使用vars定义的变量是无法被hostvars收集的,但是可以通过set_fact进行定义,这样变量就可以像facts信息一样被收集。1
2
3
4
5
6
7
8
9
- hosts : test4
tasks :
- set_fact :
testvar : testvalue
- hosts : test3
tasks :
- debug :
msg : "{{hostvars.test4.testvar}}"
inventory_hostname
inventory_hostname可以获取到被操作主机的主机名(并不是linux的主机名,而是在ansible管理端主机清单中的主机名)。如果配置清单中只是IP那么inventory_hostname获取到的则是IP。
1 | #/home/ansible/hosts文件 |
1 |
|
inventory_hostname_short
与inventory_hostname类似,inventory_hostname_short返回的则是简短名称(主机清单主机名称“.”分割的第一段名称)
1 | #/home/ansible/hosts文件 |
1 | ansible test -i /home/ansible/hosts -m debug -a "msg={{inventory_hostname_short}}" |
play_hosts
plsy_hosts可以获取到当前play操作的所有主机的主机列表名称。
1 |
|
groups
groups可以获取到主机清单中所有的组信息。
1 | #/home/ansible/hosts文件 |
1 | ansible test3 -i /home/ansible/hosts -m debug -a 'msg="{{groups}}"' |
当然可以获取指定组的信息。
1 | ansible test3 -i /home/ansible/hosts -m debug -a 'msg="{{groups.test}}"' |
group_names
获取当前操作主机在主机清单中的分组名。
1 | #/home/ansible/hosts文件 |
1 | ansible test3 -i /home/ansible/hosts -m debug -a 'msg="{{group_names}}"' |
因为test3属于test分组,而test分组又属于allhosts分组。
inventory_dir
该变量可以获取到使用的inventory文件的位置。