概括起来讲,import_tasks 是静态的,include_tasks 是动态的。静态和动态的区别集中在被 include 文件的加载时机不同。
静态的意思是被 include 的文件在 playbook 被加载时就展开了,在预处理阶段。
动态的意思是被 include 的文件在 playbook 运行时展开。
以下通过示例直观表述:
1.
[root@yangzhen ansibletest]# less playbooks/test8.yml
---
- hosts: localhost
gather_facts: no
vars:
filename: test.yml
tasks:
- import_tasks: "{{ filename }}"
- include_tasks: "{{ filename }}"
[root@yangzhen ansibletest]# less playbooks/test.yml
---
- name: Used to check difference between import_tasks and include_tasks
debug:
msg: "Test import_tasks and include_tasks"
[root@yangzhen ansibletest]# ansible-playbook playbooks/test8.yml
PLAY [localhost] *****************************************************************************************************************************************************
TASK [Used to check difference between import_tasks and include_tasks] ***********************************************************************************************
ok: [localhost] => {
"msg": "Test import_tasks and include_tasks"
}
TASK [include_tasks] *************************************************************************************************************************************************
included: /root/yz/ansibletest/playbooks/test.yml for localhost
TASK [Used to check difference between import_tasks and include_tasks] ***********************************************************************************************
ok: [localhost] => {
"msg": "Test import_tasks and include_tasks"
}
PLAY RECAP ***********************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
[root@yangzhen ansibletest]# less playbooks/test8.yml
---
- hosts: localhost
gather_facts: no
#vars:
# filename: test.yml
tasks:
- set_fact:
filename: test.yml
- import_tasks: "{{ filename }}"
- include_tasks: "{{ filename }}"
再次运行:
[root@yangzhen ansibletest]# ansible-playbook playbooks/test8.yml
ERROR! Error when evaluating variable in include name: {{ filename }}.
When using static includes, ensure that any variables used in their names are defined in vars/vars_files
or extra-vars passed in from the command line. Static includes cannot use variables from inventory
sources like group or host vars.
上述的意思是,在使用 import_tasks 引用变量时,要确保变量定义在 vars/vars_file或命令行中。如使用 var_files定义变量直观观察下。
将test8.yml修改如下
---
- hosts: localhost
gather_facts: no
vars_files:
- variable.yml
tasks:
- import_tasks: "{{ filename }}"
- include_tasks: "{{ filename }}"
[root@yangzhen ansibletest]# cat playbooks/variable.yml
---
filename: test.yml
执行
[root@yangzhen ansibletest]# ansible-playbook playbooks/test8.yml
PLAY [localhost] *****************************************************************************************************************************************************
TASK [Used to check difference between import_tasks and include_tasks] ***********************************************************************************************
ok: [localhost] => {
"msg": "Test import_tasks and include_tasks"
}
TASK [include_tasks] *************************************************************************************************************************************************
included: /root/yz/ansibletest/playbooks/test.yml for localhost
TASK [Used to check difference between import_tasks and include_tasks] ***********************************************************************************************
ok: [localhost] => {
"msg": "Test import_tasks and include_tasks"
}
PLAY RECAP ***********************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
总结:import_tasks 直接引用的变量,要定义在vars/vars_file或命令行。
2. when 关键字对 include_tasks 和 import_tasks 有着本质区别
当对 import_tasks 使用 when 进行条件判断时,when 对应的条件会被应用于 include 文件中的每一个任务,意思是每要执行一个任务时,都要先进行条件判断。总结起来就是顺序执行 include 文件中列出的每一个任务前,都要进行条件判断,满足条件就执行,不满足就跳过,需要多次判断。
当对 include_tasks 使用 when 进行条件判断时,when 对应的条件只应用一次,发生在是否include这个文件,若include,则执行这个include文件中所有的任务,不再进行其他判断。
通过示例直观分析
[root@yangzhen ansibletest]# less playbooks/test9.yml
---
- hosts: localhost
gather_facts: no
tasks:
- name: 'set variable to 0'
set_fact:
testnum: 0
- debug:
msg: 'enter the include file test10.yml'
- include_tasks: test10.yml
when: testnum == 0
- name: 'set variable to 0'
set_fact:
testnum: 0
- debug:
msg: 'enter the include file test10.yml'
- import_tasks: test10.yml
when: testnum == 0
[root@yangzhen ansibletest]# less playbooks/test10.yml
---
- set_fact:
testnum: 1
- debug:
msg: 'exective in test10.yml'
[root@yangzhen ansibletest]# ansible-playbook playbooks/test9.yml
PLAY [localhost] *****************************************************************************************************************************************************
TASK [set variable to 0] *********************************************************************************************************************************************
ok: [localhost]
TASK [debug] *********************************************************************************************************************************************************
ok: [localhost] => {
"msg": "enter the include file test10.yml"
}
TASK [include_tasks] *************************************************************************************************************************************************
included: /root/yz/ansibletest/playbooks/test10.yml for localhost
TASK [set_fact] ******************************************************************************************************************************************************
ok: [localhost]
TASK [debug] *********************************************************************************************************************************************************
ok: [localhost] => {
"msg": "exective in test10.yml"
}
TASK [set variable to 0] *********************************************************************************************************************************************
ok: [localhost]
TASK [debug] *********************************************************************************************************************************************************
ok: [localhost] => {
"msg": "enter the include file test10.yml"
}
TASK [set_fact] ******************************************************************************************************************************************************
ok: [localhost]
TASK [debug] *********************************************************************************************************************************************************
skipping: [localhost]
PLAY RECAP ***********************************************************************************************************************************************************
localhost : ok=8 changed=0 unreachable=0 failed=0
调试信息"enter the include file test10.yml"只输出了一次,发生在 include_tasks 阶段。之后将变量 testnum 重新设置为 0,条件满足时,include test10.yml, 进入 test10.yml 文件执行,在其中将 testnum 设置为 1,然后执下一条任务,进行条件判断,此时 testnum 不为0,所以不满足条件,跳过该任务。