https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse.html
有些任务是可以在其他任务里调用的,没必要在重复写一遍。
而且在一些大的任务里也推荐拆分成小的任务,通过调用与组织完成功能。
Ansible 有3种方式可以实现: includes, imports, roles。
这里介绍include与import。Ansible 2.4以后添加的include与import。
这一部分,因为我自己用的很少,所以有些可能会理解错误。如果发现错误,还请告知。
一、介绍
include_*
: 包含(include_tasks
, include_role
)
import_*
: 包含(import_playbook
, import_tasks
)
1、加载方式
include是动态加载,在运行到对应的task的时候才会加载
import 是静态加载,在playbook预解析阶段就会加载
2、相互的局限性
官方的说明:
Using `include*` does have some limitations when compared to `import*` statements:
* Tags which only exist inside a dynamic include will not show up in `--list-tags` output.
* Tasks which only exist inside a dynamic include will not show up in `--list-tasks` output.
* You cannot use `notify` to trigger a handler name which comes from inside a dynamic include (see note below).
* You cannot use `--start-at-task` to begin execution at a task inside a dynamic include.
Using `import*` can also have some limitations when compared to dynamic includes:
* As noted above, loops cannot be used with imports at all.
* When using variables for the target file or role name, variables from inventory sources (host/group vars, etc.) cannot be used.
* Handlers using `import*` will not be triggered when notified by their name, as importing overwrites the handler’s named task with the imported task list.
自己的理解:
include* 与 import*相比:
1、不会显示在--list-tags
与--list-tasks
, 当然--tags
与 --start-at-task
也不能用。
2、不能使用notify
来触发加载到handler里的任务名称。比如:
handlers:
- include_tasks: task1.yml
因为是动态加载的,notify触发的时候,任务名称还没有加载。解决办法是加一个名称。或者是添加一个listen
。notify
触发添加的名称。
handlers:
- include_tasks: task1.yml
name: test
handlers:
- include_tasks: task1.yml
listen: test
import* 与 include* 相比:
1、不能在主文件里使用循环。 如:
tasks:
- import_tasks: task1.yml
loop:
- one
- two
报语法错误。 loop需要在加载的文件里写好。 可能是因为静态加载,每个文件都是一完整的任务,不能添加东西。
include_tasks是可以的, 加载的文件也可以加loop, 但是不要加完以后再在主文件加,会冲突。
2、将变量用于目标文件或角色名称时,不能使用inventory(主机/主机组等)中的变量。
也没测试出来怎么回事,这样测试的,可能方法不对。
- hosts: webserver
tasks:
- import_tasks: task1.yml
[root@lvs playbook]# cat task1.yml
- name: test
file: name=/tmp/{{http_port}} state=touch
3、不能使用notify
来触发handler里添加的任务名称, 与include正好相反。
include是必须在主文件里添加任务名称, import是不能添加,添加也没用, import加载会覆盖任务设置,就算是没有设置name, 也会把主文件里的name覆盖为空。 就算添加listen也没用。
比如:
子文件:
- name: test
file: name=/tmp/{{http_port}} state=touch
主文件:
tasks:
- shell: echo '123'
notify: test
handlers:
- import_tasks: task1.yml
listen: ttt
需要notify
触发子文件里的名称, import加载以后会覆盖主文件里添加的任务参数。
3、总结
各个子任务的配置还是在各个子文件,除非遇到特殊情况, 特殊情况就再专门测试。
只是做一些记录。
import_tasks
任务相关设置大部分只能在子文件里设置。
发现vars
可以在主文件的任务里定义。
tasks:
- import_tasks: task1.yml
vars:
user: sssssy
notify
只能在子文件里,不然无法生效。
include_tasks
任务相关设置可以在文件里设置也可以在主文件里设置。 一些需要预先统计的设置,如任务名称,如果要使用就需要在主文件里设置,比如,从指定任务开始执行。
而notify
只能在子文件里定义。
二、使用
1、import_playbook
加载完整的包含hosts的playbook文件。
例子:
webserver子文件:
[root@lvs playbook]# cat webserver.yml
- hosts: webserver
tasks:
- name: install nginx
yum: name=nginx state=present
dbserver子文件:
[root@lvs playbook]# cat dbserver.yml
- hosts: dbserver
tasks:
- name: install mariadb
yum: name=mariadb-server state=present
main主文件:
[root@lvs playbook]# cat main.yml
---
- import_playbook: webserver.yml
- import_playbook: dbserver.yml
2、import_tasks
静态导入任务文件。觉得这个还是比较常用的。
比如:分别设置 db, nginx, php, tomcat 的task文件。 就可以分别组成lnmp, lnmt等。
例子:
nginx.yml
[root@lvs playbook]# cat nginx.yml
- name: install nginx
yum: name=nginx state=present
- name: push config
copy: src=/etc/nginx/nginx.conf
dest=/etc/nginx/nginx.conf
php.yml
[root@lvs playbook]# cat php.yml
- name: install php
yum:
name: php, php-fpm
state: present
mysql.yml
[root@lvs playbook]# cat mysql.yml
- name: install mariadb
yum: name=mariadb-server state=present
lnmp.yml
[root@lvs playbook]# cat lnmp.yml
- hosts: webserver
tasks:
- import_tasks: nginx.yml
- import_tasks: php.yml
- import_tasks: mysql.yml
3、include_tasks
上面的例子也可以使用include_tasks
替换import_tasks
。
他们之间的区别上面也说了,只是官方也没有说的很细,有些细节还需要自己测试。