Working with Includes and Imports
1. Understanding Static vs Dynamic
| Aspect | Static Includes | Dynamic Imports |
|---|---|---|
| Execution Timing | Processed at parse time | Processed at runtime |
| Variable Scope | Variables defined in included files are available in the including file's scope | Variables from imported files are not automatically available in the including file's scope |
| File Inclusion | Uses include directive |
Uses import directive |
| Conditional Logic | Cannot use conditionals directly in includes | Can use conditionals to control import behavior |
| Looping | Cannot loop over includes | Can loop over imports |
| Use Case | Best for static configuration files or templates that do not change during playbook execution | Best for dynamic content where variables or conditions determine what gets included |
2. Including Tasks
| Property | Description | Values |
|---|---|---|
| include_tasks | Loads and executes a set of tasks from a file | tasks/main.yml |
| import_tasks | Loads and executes a set of tasks from a file at parse time | tasks/main.yml |
Note:
include_tasks is evaluated at runtime, while import_tasks is evaluated at parse time.
3. Importing Tasks
| Option | Values | Notes |
|---|---|---|
| import_tasks | tasks/main.yml |
Imports a list of tasks from a file |
| include_tasks | tasks/main.yml |
Includes a list of tasks from a file (dynamic) |
Example: Including tasks dynamically
- name: Include tasks dynamically
include_tasks: "{{ item }}.yml"
loop:
- tasks/step1
- tasks/step2
Note:
import_tasks is processed at parse time, while include_tasks is processed at runtime.
4. Including Playbooks
| Directive | Description | Usage | Notes |
|---|---|---|---|
| include_playbook | Includes another playbook file into the current playbook | include_playbook: other_playbook.yml |
Used to break large playbooks into smaller, manageable files |
| import_playbook | Imports another playbook at parse time | import_playbook: other_playbook.yml |
Available in Ansible 2.2+ |
Example: Including a Playbook
- name: Main playbook
hosts: all
tasks:
- name: Run a task
debug:
msg: "Hello World"
- name: Include another playbook
include_playbook: web_setup.yml
Note:
include_playbook is evaluated at runtime, while import_playbook is evaluated at parse time.
5. Importing Playbooks
| Option | Values | Notes |
|---|---|---|
| import_playbook | playbooks/web_setup.yml |
Path to the playbook to import |
Example: Importing a Playbook
- name: Main playbook
hosts: all
tasks:
- name: Import web setup playbook
import_playbook: playbooks/web_setup.yml
Note:
import_playbook is processed at playbook parsing time, not at runtime.
Warning: Using
import_playbook inside loops or conditionals is not supported.
6. Including Roles
| Property | Description | Example |
|---|---|---|
| roles | List of roles to include in the playbook | roles: |
| role | Name of the role to include | - role: webserver |
Note: Roles are included in the order they appear in the list.
Warning: Ensure roles are defined in the
roles/ directory or specified via ansible.cfg.
7. Importing Roles
| Property | Description | Example |
|---|---|---|
| import_role | Used to import a role into the current playbook. It is processed at playbook parsing time. | |
| include_role | Used to include a role into the current playbook. It is processed at runtime and allows for variables to be passed. | |
Example: Using include_role with vars
- name: Setup application server
hosts: app_servers
include_role:
name: nodejs_app
vars:
app_port: 3000
env: production
Note:
import_role is processed at parse time, while include_role is processed at run time. This affects variable scoping and conditional execution.
Key Differences
- import_role: Processed at parse time, no variable interpolation.
- include_role: Processed at run time, supports variable interpolation and conditionals.
8. Passing Variables
| Variable Type | Description | Usage Example |
|---|---|---|
| host_vars | Variables specific to a host | ansible_host: 192.168.1.10 |
| group_vars | Variables specific to a group of hosts | http_port: 80 |
| inventory_vars | Variables defined in inventory files | ansible_user: admin |
| playbook_vars | Variables defined in playbook files | app_version: "v2.0" |
| extra_vars | Variables passed at runtime via CLI | ansible-playbook site.yml -e "env=prod" |
Example: Passing Variables to a Task
- name: Use variable in task
debug:
msg: "The web server is running on port {{ http_port }}"
Example: Using Extra Vars in Playbook
---
- hosts: webservers
vars:
app_port: "{{ port }}"
tasks:
- name: Start application
command: /app/start.sh --port {{ app_port }}
9. Using Conditionals
| Condition | Description | Usage |
|---|---|---|
| when | Conditionally execute a task based on the evaluation of a boolean expression. | when: ansible_facts.os_family == 'RedHat' |
| when (with variables) | Use variables in conditional expressions. | when: deploy_app == true |
| when (with Jinja2) | Use Jinja2 expressions in conditionals. | when: "{{ item.value }} > 10" |
Example: Using when with a variable
- name: Install package only on Ubuntu
apt:
name: nginx
state: present
when: ansible_distribution == 'Ubuntu'
Example: Using when with a complex condition
- name: Configure firewall only if not in production
ufw:
rule: allow
port: 22
when: not production_env
Note: The
when clause can be used in tasks, handlers, and blocks.
Warning: Be cautious with complex Jinja2 expressions in
when clauses as they can impact performance.
10. Using Tags
| Tag | Description | Usage |
|---|---|---|
| tag | Assigns a tag to a task or include | tag: webserver |
| tags | Assigns multiple tags to a task or include | tags: [web, database] |
Example: Using Tags in Playbook
---
- hosts: all
tasks:
- name: Install Apache
apt:
name: apache2
state: present
tags: [web, http]
- name: Configure Database
template:
src: db.conf.j2
dest: /etc/db.conf
tags: [database, config]
Note: Tags can be used to selectively run or skip tasks using the
--tags and --skip-tags CLI options.
11. Looping Over Includes
| Property | Description | Example |
|---|---|---|
| loop | Used to iterate over a list of includes | include_tasks: "{{ item }}" |
| loop_var | Variable name for the current item in the loop | loop_var: task_file |
Example: Looping Over Include Files
- name: Loop over include files
include_tasks: "{{ item }}"
loop:
- task1.yml
- task2.yml
- task3.yml
12. Understanding Precedence
| Include/Import Type | File Extension | Precedence Level | Notes |
|---|---|---|---|
| include | .yml, .yaml |
1 | Processed at task execution time |
| import | .yml, .yaml |
2 | Processed at parse time |
Note: The precedence order affects how variables and tasks are handled in Ansible playbooks.