包含与导入文件
如果playbook很长或很复杂,我们可以将其分成较小的文件以便于管理。可采用模块化方式将多个playbook组合为一个主要playbook,或者将文件中的任务列表插入play。这样可以更轻松地在不同项目中重用play或任务序列。
包含或导入文件
Ansible可以使用两种操作将内容带入playbook。可以包含内容,也可以导入内容。
包含内容是一个动态操作。在playbook运行期间,Ansible会在内容到达时处理所包含的内容。
导入内容是一个静态操作。在运行开始之前,Ansible在最初解析playbook时预处理导入的内容。
导入playbook
import_playbook指令允许将包含play列表的外部文件导入playbook。换句话说,可以把一个或多个额外playbook导入到主playbook中。
由于导入的内容是一个完整的playbook,因此import_playbook功能只能在playbook的顶层使用,不能在play内使用。如果导入多个playbook,则将按顺序导入并运行它们。
导入两个额外playbook的主playbook的简单示例如下所示:
[root@localhost ansible]# tree /etc/ansible/
/etc/ansible/
├── installed.yml # 安装httpd的playbook
├── main.yml # 组合两个playbook的playbook
├── started.yml # 启动httpd的playbook
[root@localhost ansible]# cat installed.yml
---
- hosts: 192.168.220.8
tasks:
- name: installed httpd
yum:
name: httpd
state: latest
[root@localhost ansible]# cat started.yml
---
- hosts: 192.168.220.8
tasks:
- name: started httpd
service:
name: httpd
state: started
[root@localhost ansible]# cat main.yml # 执行这个playbook
- name: install
import_playbook: installed.yml
- name: start
import_playbook: started.yml
还可以使用导入的playbook在主playbook中交替play。
- name: Play 1
hosts: localhost
tasks:
- debug:
msg: Play 1
- name: Import Playbook
import_playbook: play2.yml
在此例中,Play 1首先运行,然后运行从play2.ymlplaybook中导入的play。
导入和包含任务
导入任务
可以将任务文件中的任务列表导入或包含在play中。任务文件是包含一个任务平面列表的文件
可以使用import_tasks功能将任务文件静态导入playbook内的play中。导入任务文件时,在解析该playbook时将直接插入该文件中的任务。Playbook中的import_tasks的位置控制插入任务的位置以及运行多个导入的顺序。
[root@localhost ansible]# tree /etc/ansible/
/etc/ansible/
├── installed.yml # 安装httpd的任务
├── main.yml # 组合两个任务的playbook
├── started.yml # 启动httpd的任务
[root@localhost ansible]# cat installed.yml
- name: installed httpd
yum:
name: httpd
state: latest
[root@localhost ansible]# cat started.yml
- name: started httpd
service:
name: httpd
state: started
[root@localhost ansible]# cat main.yml # 执行该playbook,将导入上面两个任务
---
- hosts: 192.168.220.8
tasks:
- import_tasks: installed.yml
- import_tasks: started.yml
导入任务文件时,在解析该playbook时将直接插入该文件中的任务。由于import_tasks在解析playbook时静态导入任务,因此对其工作方式有一些影响。
- 使用 import_tasks 功能时,导入时设置的when等条件语句将应用于导入的每个任务
- 无法将循环用于import_tasks功能
- 如果使用变量来指定要导入的文件的名称,则将无法使用主机或组清单变量
包含任务文件
可以使用include_tasks功能将任务文件动态导入playbook内的play中,和导入任务区别不大。
[root@localhost ansible]# cat installed.yml
- name: installed httpd
yum:
name: httpd
state: latest
[root@localhost ansible]# cat started.yml
- name: started httpd
service:
name: httpd
state: started
[root@localhost ansible]# cat main.yml # 执行该playbook,将包含上面两个任务
---
- hosts: 192.168.220.8
tasks:
- include_tasks: installed.yml # 包含任务
- include_tasks: started.yml
[root@localhost ansible]# ansible-playbook main.yml
.....
TASK [include_tasks] ***********************************************************
included: /etc/ansible/installed.yml for 192.168.220.8 # 执行时会显示任务应用于哪个主机
TASK [installed httpd] *********************************************************
ok: [192.168.220.8]
TASK [include_tasks] ***********************************************************
included: /etc/ansible/started.yml for 192.168.220.8 # 执行时会显示任务应用于哪个主机
TASK [started httpd] ***********************************************************
ok: [192.168.220.8]
.....
在play运行并且这部分play到达前,include_tasks功能不会处理playbook中的内容。Playbook内容的处理顺序会影响包含任务功能的工作方式。
-
使用include_tasks功能时,包含时设置的when等条件语句将确定任务是否包含在play中
-
如果运行ansible-playbook --list-tasks以列出playbook中的任务,则不会显示已包含任务文件中的任务。将显示包含任务文件的任务。相比之下,import_tasks功能不会列出导入任务文件的任务,而列出已导入任务文件中的各个任务
[root@localhost ansible]# cat main.yml # 导入任务与包含任务 --- - hosts: 192.168.220.8 tasks: - import_tasks: installed.yml # 导入任务 - include_tasks: started.yml # 包含任务 [root@localhost ansible]# ansible-playbook main.yml --list-tasks # 导入任务与包含任务使用命令查看区别 playbook: main.yml play #1 (192.168.220.8): 192.168.220.8 TAGS: [] tasks: installed httpd TAGS: [] # 导入任务显示具体要执行的任务 include_tasks TAGS: [] # 包含任务不显示具体要执行的任务
-
不能使用ansible-playbook --start-at-task从已包含任务文件中的任务开始执行playbook
-
不能使用notify语句触发已包含任务文件中的处理程序名称。可以在包含整个任务文件的主playbook中触发处理程序,在这种情况下,已包含文件中的所有任务都将运行
任务文件的用例
请参考下面的示例,在这些情景中将任务组作为与playbook独立的外部文件来管理或许有所帮助:
- 如果新服务器需要全面配置,则管理员可以创建不同的任务集.合,分别用于创建用户、安装软件包、配置服务、配置特权、设置对共享文件系统的访问权限、强化服务器、安装安全更新,以及安装监控代理等。每一任务集合可通过单独的自包含任务文件进行管理
- 如果服务器由开发人员、系统管理员和数据库管理员统一管理,则每个组织可以编写自己的任务文件,再由系统经理进行审核和集成
- 如果服务器要求特定的配置,它可以整合为按照某一条件来执行的一组任务。换句话说,仅在满足特定标准时才包含任务
- 如果一组服务器需要运行某一项/组任务,则它/它们可以仅在属于特定主机组的服务器上运行
管理任务文件
为方便管理,可以创建专门用于任务文件的目录,并将所有任务文件保存在该目录中。然后playbook就可以从该目录包含或导入任务文件。这样就可以构建复杂的playbook,同时简化其结构和组件的管理。
为外部play和任务定义变量
使用Ansible的导入和包含功能将外部文件中的play或任务合并到playbook中极大地增强了在Ansible环境中重用任务和playbook的能力。为了最大限度地提高重用可能性,这些任务和play文件应尽可能通用。变量可用于参数化play和任务元素,以扩大任务和play的应用范围。
例如,以下任务文件将安装Web服务所需的软件包,然后启用并启动必要的服务。
---
- name: Install the httpd package
yum:
name: httpd
state: latest
- name: Start the httpd service
service:
name: httpd
enabled: True
state: started
如果如下例所示对软件包和服务元素进行参数化,则任务文件也可用于安装和管理其他软件及其服务,而不仅仅用于Web服务。
[root@localhost ansible]# cat installed.yml # 安装服务任务
- name: installed packages
yum:
name: "{{ packages }}"
state: latest
[root@localhost ansible]# cat started.yml # 安装服务任务
- name: service packages
service:
name: "{{ packages }}"
state: started
随后,在将任务文件合并到一个playbook中时,定义用于执行该任务的变量,如下所示:
[root@localhost ansible]# cat main.yml
---
- hosts: 192.168.220.8
tasks:
- name: test
import_tasks: installed.yml # 导入安装服务任务
import_tasks: started.yml # 导入启动服务任务
vars:
packages: httpd # 变量
Ansible使传递的变量可用于从外部文件导入的任务。
使用相同的技术使play文件更具有可重用性。将play文件合并到playbook中时,传递变量以用于执行该play,如下所示:
...output omitted...
- name: Import play file and set the variable
import_playbook: play.yml
vars:
package: mariadb