Limited Time Offer!

For Less Than the Cost of a Starbucks Coffee, Access All DevOpsSchool Videos on YouTube Unlimitedly.
Master DevOps, SRE, DevSecOps Skills!

Enroll Now

Ansible Include and Import with differences explanined!

This is one of the most frequest questions being asked in my workshop is that differences between using import or include in Ansible. For example import_role or include_role, what should be behaviour and what to expect?

We know that include could be applied to tasks, plays and handlers. The bare include task (which was used for both Task files and Playbook-level includes) is still available, however it is now considered deprecated and introduced with include_tasks, include_role and include_role.

With filename variable substitution, the code could become much more clean.


include: “{{ codename }}.yml”

We also know that include using(include and import) could be dynamic or static.

Differences Between Static and Dynamic

Ansible has two modes of operation for reusable content with Including and Importing and Roles: dynamic and static.

The main difference is:

All import* statements are pre-processed at the time playbooks are parsed.
All include* statements are processed as they encountered during the execution of the playbook.
So import is static, include is dynamic.

Background
In Ansible 2.0, the concept of dynamic includes was introduced. Due to some limitations with making all includes dynamic in this way, the ability to force includes to be static was introduced in Ansible 2.1.

Static import
If you use any import* Task (import_playbook, import_tasks, etc.), it will be static.

Dynamic Include
If you use any include* Task (include_tasks, include_role, etc.), it will be dynamic.

The two modes of operation are pretty simple:

  • Ansible pre-processes all static imports during Playbook parsing time.
  • Dynamic includes are processed during runtime at the point in which that task is encountered.

When it comes to Ansible task options like tags and conditional statements (when:):

  • For static imports, the parent task options will be copied to all child tasks contained within the import.
  • For dynamic includes, the task options will only apply to the dynamic task as it is evaluated, and will not be copied to child tasks.

The primary advantage of using include* statements is looping. When a loop is used with an include, the included tasks or role will be executed once for each item in the loop.

- import_tasks: x.yml 
  with_items: [1,2,3] 

This willi import x.yml one time and every imported task will now run 
and loop over 1,2,3 

- include_tasks: x.yml 
  with_items: [1,2,3] 

This will include x.yml 3 times and set the 'item' variable to 1, 2 
and 3 respectively 

In order to conclude this, Basically import tasks will be parsed at the beginning when you run the playbook, but include tasks will only be parsed at the moment Ansible hits them.

Means, with include Running the Playbook which has list of tasks will execute until the error tasks are found, which is in included file.

On other end, Wait, with import, it will flag a error to begin with only. The reason is because the import_role task is pre-processed at the time playbooks are parsed. So it found the syntax error much earlier and so it never was able to even run our first task with the debug module.

This is an example that really emphasizes the fact that import is parsed quite early. This is what is referred to as static.

Ansible include and import has following module which must be explored

import
import_playbook
import_role
import_tasks
include
include_vars
include_playbook
include_role
include_tasks

Reference

Rajesh Kumar
Follow me
Latest posts by Rajesh Kumar (see all)
Subscribe
Notify of
guest
1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Niranjan
Niranjan
1 year ago

The primary advantage of using include* statements is looping. When a loop is used with an include, the included tasks or role will be executed once for each item in the loop.

- import_tasks: x.yml 
  with_items: [1,2,3] 

This willi import x.yml one time and every imported task will now run 
and loop over 1,2,3 

- include_tasks: x.yml 
  with_items: [1,2,3] 

This will include x.yml 3 times and set the 'item' variable to 1, 2 
and 3 respectively 

Can you provide an example playbook here?

1
0
Would love your thoughts, please comment.x
()
x