Skip to main content

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

Example: Static Include

- name: Use static include
  hosts: all
  tasks:
    - include: vars.yml

Example: Dynamic Import

- name: Use dynamic import
  hosts: all
  tasks:
    - import: vars.yml

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

Example: Using include_tasks

- name: Include tasks from a file
  include_tasks: create_user.yml

Example: Using import_tasks

- name: Import tasks from a file
  import_tasks: setup_server.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: Importing tasks from a file

- name: Import tasks from a file
  import_tasks: tasks/main.yml

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

Example: Including a Role

---
- hosts: all
  roles:
    - webserver

Example: Including Multiple Roles

---
- hosts: all
  roles:
    - webserver
    - database
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.
- name: Import a role
  import_role:
    name: common
include_role Used to include a role into the current playbook. It is processed at runtime and allows for variables to be passed.
- name: Include a role with variables
  include_role:
    name: webserver
  vars:
    http_port: 8080

Example: Using import_role

- name: Setup web server
  hosts: webservers
  import_role:
    name: nginx

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.

Example: Running Tasks with Specific Tags

ansible-playbook site.yml --tags "web"

Example: Skipping Tasks with Specific Tags

ansible-playbook site.yml --skip-tags "database"

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.

Example: Precedence in Playbook

- name: Example Playbook
  hosts: all
  tasks:
    - include: vars.yml
      vars:
        var1: "included"
    - import: tasks.yml

Was this article helpful?