ansible 六、playbook(复用)

大番茄 2020年02月16日 831次浏览

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触发的时候,任务名称还没有加载。解决办法是加一个名称。或者是添加一个listennotify触发添加的名称。

  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
他们之间的区别上面也说了,只是官方也没有说的很细,有些细节还需要自己测试。