在 Ansible 2.4 中,该include模块已弃用。取而代之的是,它附带了两个替换模块,import_tasks以及include_tasks. 但它们有非常相似的描述:
include_tasks:包含一个文件,其中包含要在当前剧本中执行的任务列表。import_tasks:导入要添加到当前剧本以供后续执行的任务列表。什么时候用前者,什么时候用后者?
Kon*_*rov 116
文档中有很多关于这个主题的内容:
主要区别在于:
所有
import*语句都在解析 playbook 时进行预处理。
所有include*语句都按照它们在剧本执行期间遇到的方式进行处理。
所以import是静态的,include是动态的。
根据我的经验,您应该import在处理逻辑“单元”时使用。例如,将一长串任务分成子任务文件:
主文件:
- import_tasks: prepare_filesystem.yml
- import_tasks: install_prerequisites.yml
- import_tasks: install_application.yml
Run Code Online (Sandbox Code Playgroud)
但是您会习惯于include处理不同的工作流程并根据一些动态收集的事实做出决定:
安装先决条件:
- include_tasks: prerequisites_{{ ansible_os_family | lower }}.yml
Run Code Online (Sandbox Code Playgroud)
x-y*_*uri 36
导入是静态的,包含是动态的。导入发生在解析时,包括在运行时。
导入基本上用文件中的任务替换任务。运行时没有导入任务。因此,像tags, 和when(很可能是其余的)这样的属性被复制到每个导入的任务中。
包括确实被执行了。tags和when包含的任务仅适用于任务本身。
如果导入任务未标记,则会执行来自导入文件的标记任务。如果包含任务未标记,则不会从包含文件执行任何任务。
如果导入任务被标记,则导入文件中的所有任务都会被执行。如果包含任务被标记,则只有包含文件中的标记任务才会被执行。
进口限制:
with_*或loop属性一起使用限制包括:
--list-tags 不显示包含文件中的标签--list-tasks 不显示包含文件中的任务notify触发来自动态包含内部的处理程序名称--start-at-task在动态包含中的任务处开始执行对我来说,这基本上归结为导入不能与loop属性一起使用的事实。
在这种情况下,导入肯定会失败:
# playbook.yml
- import_tasks: set-x.yml
when: x is not defined
# set-x.yml
- set_fact
x: foo
- debug:
var: x
Run Code Online (Sandbox Code Playgroud)
debug不执行,因为它继承when自import_tasks任务。因此,不会更改导入任务when属性中使用的变量的导入任务文件。
我有一个从导入开始的策略,但是一旦我需要一个包含,我就确保包含的文件或其子文件没有导入任何内容。但这很难维持。现在还不清楚它是否会保护我免受麻烦。我的意思是,不建议混合包含和导入。
我不能只使用导入,因为我偶尔需要循环。我可能可以切换到只包含。但我决定在任何地方都切换到导入,除非我需要循环。我决定亲身体验所有那些棘手的边缘情况。也许我的剧本中不会有任何内容。或者希望我能找到一种方法让它发挥作用。
UPD创建一个可以多次导入但只执行一次的任务文件的可能有用的技巧:
- name: ...
...
when: not _file_executed | default(False)
- name: ...
...
when: not _file_executed | default(False)
...
- name: Set _file_executed
set_fact:
_file_executed: True
Run Code Online (Sandbox Code Playgroud)
UPD混合包含和导入的真正预期效果是包含任务的变量覆盖导入任务的变量:
playbook.yml:
- hosts: all
tasks:
- import_tasks: 2.yml
vars:
v1: 1
- include_tasks: 2.yml
vars:
v1: 1
Run Code Online (Sandbox Code Playgroud)
2.yml:
- import_tasks: 3.yml
vars:
v1: 2
Run Code Online (Sandbox Code Playgroud)
3.yml:
- debug:
var: v1 # 2 then 1
Run Code Online (Sandbox Code Playgroud)
可能是因为include_tasks首先导入文件,然后应用其vars指令。
实际上,它也可以像这样重现:
playbook.yml:
- hosts: all
tasks:
- import_tasks: 2.yml
vars:
v1: 1
- include_tasks: 2.yml
vars:
v1: 1
Run Code Online (Sandbox Code Playgroud)
2.yml:
- debug:
var: v1 # 2 then 1
vars:
v1: 2
Run Code Online (Sandbox Code Playgroud)
UPD混合包含和导入的另一种情况。
playbook.yml:
- hosts: all
tasks:
# say, you're bound to use include here (because you need a loop)
- include_tasks: 2.yml
vars:
https: yes
Run Code Online (Sandbox Code Playgroud)
2.yml:
- import_tasks: 3.yml
when: https
Run Code Online (Sandbox Code Playgroud)
3.yml:
- import_tasks: 4.yml
vars:
https: no # here we're trying to temporarily override the https var
- import_tasks: 4.yml
Run Code Online (Sandbox Code Playgroud)
4.yml:
- debug:
var: https
Run Code Online (Sandbox Code Playgroud)
我们得到trueand true,参见前一种情况(include_tasks'vars 优先于import_tasks''s)。为了避免这种情况,我们可以切换到包含在3.yml. 但是第一个包含在3.yml被跳过。由于它继承when: https自父任务,所以第一个任务基本上是这样写的:
- import_tasks: 4.yml
vars:
https: no # here we're trying to temporarily override the https var
when: https
Run Code Online (Sandbox Code Playgroud)
解决方案是也切换到包含2.yml。这可以防止传播when: https到子任务。
| 归档时间: |
|
| 查看次数: |
78077 次 |
| 最近记录: |