Ansible Playbook 任务导入
在使用 Playbook 时,可能会存在一些经常使用的 Play,这时可以利用 Playbook 导入的方式来重复利用同一个 Play,被导入的任务是一个任务模板(没有 hosts
、tasks
字段,可以看下边的例子)。
Playbook 任务导入有两种模式:
ansible.builtin.import_tasks
:静态导入tasks
,在 Playbook 执行前导入 Playansible.builtin.include_tasks
:动态导入tasks
,在 Playbook 执行到某一个任务时开始导入ansible.builtin.import_role
:静态导入role
,在 Playbook 执行前导入 Playansible.builtin.include_role
:动态导入role
,在 Playbook 执行到某一个任务时开始导入ansible.builtin.import_playbook
:静态导入Playbook
,在 Playbook 执行前导入 Play
这里主要区别是静态和动态,至于是
tasks
还是role
,区别不大,后边只用ansible.builtin.import_tasks
和ansible.builtin.include_tasks
举例。
创建可导入的模板
下边是一个可重复利用的 Play 模板,文件为 /tmp/other.yml
:
[root@study ansible]# cat /tmp/other.yml
- name: set
set_fact:
x: foo
- name: print
debug:
var: x
静态导入
下边是静态导入的 Playbook:
[root@study ansible]# cat /tmp/import.yml
- name: test
hosts: localhost
tasks:
- import_tasks: /tmp/other.yml
when: x is not defined
这里简单解释一下,import_tasks
会在任务执行前将 /tmp/other.yml
任务导入,然后开始执行 Playbook,所以实际执行的 Playbook 如下:
- name: test
hosts: localhost
gather_facts: false
tasks:
- name: set
set_fact:
x: foo
when: x is not defined
- name: print
debug:
var: x
when: x is not defined
相当于被导入的每个 Play 都会添加 when
判断,第一个 Play 会设置变量 x
,因为变量 x
存在了,所以第二个 Play 会跳过,执行结果如下:
[root@study ansible]# ansible-playbook /tmp/import.yml
PLAY [test] *****************************************************************************************************
TASK [set] ******************************************************************************************************
ok: [localhost]
TASK [print] ****************************************************************************************************
skipping: [localhost]
PLAY RECAP ******************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
动态导入
下边是动态导入的 Playbook:
[root@study ansible]# cat /tmp/include.yml
- name: test
hosts: localhost
gather_facts: false
tasks:
- include_tasks: /tmp/other.yml
when: x is not defined
这个会在 Playbook 开始后执行到 include_tasks
这一个 Play 时才开始导入 Play,虽然这个也有判断,但是这个判断只判断任务是否导入(变量不存在导入 Play,变量存在跳过导入),所以被导入的 Play 都会被执行,执行结果如下:
[root@study ansible]# ansible-playbook /tmp/include.yml
PLAY [test] *****************************************************************************************************
TASK [include_tasks] ********************************************************************************************
included: /tmp/other.yml for localhost
TASK [set] ******************************************************************************************************
ok: [localhost]
TASK [print] ****************************************************************************************************
ok: [localhost] => {
"x": "foo"
}
PLAY RECAP ******************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
静态导入和动态导入的区别
这里直接引用官网的表格:
Include_* | Import_* | |
---|---|---|
重用类型 | 动态 | 静态 |
何时处理 | 运行时,当遇到时 | 在 Playbook 解析期间预处理 |
任务或 Play | 所有包含都是任务 | import_playbook 不能是任务 |
任务选项 | 仅应用于包含任务本身 | 应用于导入中的所有子任务 |
从循环调用 | 为每个循环项执行一次 | 不能在循环中使用 |
使用 --list-tags |
未列出包含中的标签 | 所有标签都与 --list-tags 一起显示 |
使用 --list-tasks |
未列出包含中的任务 | 所有任务都与 --list-tasks 一起显示 |
通知处理程序 | 无法触发包含中的处理程序 | 可以触发单独导入的处理程序 |
使用 --start-at-task |
无法从包含中的任务开始 | 可以从导入的任务开始 |
使用清单变量 | 可以 include_*: {{ inventory_var }} |
无法 import_*: {{ inventory_var }} |
对于剧本 (playbooks) | 没有 include_playbook |
可以导入完整的剧本 |
对于变量文件 | 可以包含变量文件 | 使用 vars_files: 导入变量 |
针对
notify
,include_tasks
只支持整体触发,import_tasks
支持导入的单个 Play 触发。
引用官网的例子:
导入的 Play 模板:
# restarts.yml
- name: Restart apache
ansible.builtin.service:
name: apache
state: restarted
- name: Restart mysql
ansible.builtin.service:
name: mysql
state: restarted
动态导入的 notify
:
- name: Trigger an included (dynamic) handler
hosts: localhost
handlers:
- name: Restart services
include_tasks: restarts.yml
tasks:
- command: "true"
notify: Restart services
静态导入的 notify
:
- name: Trigger an imported (static) handler
hosts: localhost
handlers:
- name: Restart services
import_tasks: restarts.yml
tasks:
- command: "true"
notify: Restart apache
- command: "true"
notify: Restart mysql