As your Ansible automation grows, managing everything inside a single playbook can get overwhelming. That’s where importing or including playbooks comes in handy.
With import_playbook and include_tasks, you can break large automation scripts into smaller, reusable components—making your playbooks easier to read, debug, and scale.
In this guide, you’ll learn how to use both methods effectively with real-world examples.
Table of Contents
What is the Difference Between import_playbook and include_tasks?
Let’s start by understanding the key differences:
| Feature | import_playbook | include_tasks | 
|---|---|---|
| Type | Static inclusion | Dynamic inclusion | 
| Use Case | Reuse entire playbooks | Include tasks based on conditions | 
| Evaluated | Before playbook execution | During playbook execution | 
| Use Inside Tasks | ❌ Not supported | ✅ Yes | 
When to Use Which
✅ Use import_playbook when:
- You want to reuse full playbooks across projects. 
- You don’t need dynamic conditions. 
✅ Use include_tasks when:
- You want to conditionally run different tasks based on variables or facts. 
- You want to modularize logic inside a playbook dynamically. 
Basic Syntax
Here’s how to use import_playbook and include_tasks in Ansible:
Using import_playbook
# main_playbook.yml
- import_playbook: playbooks/webserver_setup.ymlUsing include_tasks
# main_playbook.yml
- include_tasks: tasks/configure_firewall.ymlThe main difference is that import_playbook is processed before execution, while include_tasks is processed dynamically during execution.
Example 1: Using import_playbook
Let’s look at a scenario where we use import_playbook to include another playbook.
Here is a directory structure of the Ansible project:
my_ansible_project/
├── main_playbook.yml
└── playbooks/
    └── webserver_setup.ymlContent of webserver_setup.yml
---
- name: Setup Web Server
  hosts: webservers
  tasks:
    - name: Install NGINX
      ansible.builtin.yum:
        name: nginx
        state: present
    - name: Start and Enable NGINX
      ansible.builtin.systemd:
        name: nginx
        state: started
        enabled: trueContent of main_playbook.yml
---
- import_playbook: playbooks/webserver_setup.ymlNow, run the main playbook.
 # ansible-playbook main_playbook.ymlOutput:
PLAY [Setup Web Server] ********************************************************
TASK [Install NGINX] ***********************************************************
changed: [webserver1]
TASK [Start and Enable NGINX] **************************************************
changed: [webserver1]
PLAY RECAP *********************************************************************
webserver1                 : ok=2    changed=2    unreachable=0    failed=0In this example, we used import_playbook to include the webserver_setup.yml playbook. The tasks from the imported playbook are executed as if they were written directly in the main playbook.
Example 2: Using include_tasks
Now, let’s see an example of using include_tasks to dynamically include tasks based on conditions.
Here is a directory structure:
my_ansible_project/
├── main_playbook.yml
└── tasks/
    ├── setup_dev.yml
    └── setup_prod.ymlContent of setup_dev.yml
---
- name: Install Development Tools
  ansible.builtin.yum:
    name: git
    state: presentContent of setup_prod.yml
---
- name: Install Production Monitoring Tools
  ansible.builtin.yum:
    name: htop
    state: presentContent of main_playbook.yml
---
- hosts: all
  tasks:
    - include_tasks: tasks/setup_dev.yml
      when: env == 'dev'
    - include_tasks: tasks/setup_prod.yml
      when: env == 'prod'Now, run the main playbook with an extra variable (env=dev).
 # ansible-playbook main_playbook.yml -e "env=dev"Output:
PLAY [all] *********************************************************************
TASK [Install Development Tools] ***********************************************
changed: [host1]
PLAY RECAP *********************************************************************
host1                     : ok=1    changed=1    unreachable=0    failed=0In this example, include_tasks is used to dynamically include either setup_dev.yml or setup_prod.yml based on the value of the env variable. This allows for conditional task execution, providing flexibility in how tasks are executed.
Advanced Usage: Conditional Task Inclusion
You can use include_tasks with conditions based on facts gathered during the playbook run.
The following example executes tasks conditionally using the when statement:
---
- hosts: all
  tasks:
    - include_tasks: tasks/setup_ubuntu.yml
      when: ansible_os_family == 'Debian'
    - include_tasks: tasks/setup_centos.yml
      when: ansible_os_family == 'RedHat'This setup dynamically includes task files based on the detected OS family (Debian or RedHat). It helps in executing platform-specific tasks.
Common Pitfalls and Tips
- import_playbookmust be at the top level, not under- tasks:
- Ensure files exist and paths are correct relative to the calling playbook.
- Use - include_tasksfor conditional logic;- import_tasksbehaves like a static version but is rarely used now.
Conclusion
Organizing large Ansible projects becomes easier with import_playbook and include_tasks. Use these tools to:
- Reuse logic across environments 
- Apply OS-specific configurations 
- Write cleaner, more modular playbooks 
With a bit of planning, your automation scripts can stay clean, efficient, and scalable.
FAQs
1. Can I use conditions with import_playbook?
No, conditions (like when) are not supported with import_playbook. Use include_tasks if you need conditional logic.
2. How do I include tasks from another playbook file?
Use import_playbook: filename.yml in your main playbook or include_tasks: filename.yml within a task block.
3. Why should I use include_tasks instead of copying tasks directly?
Using include_tasks helps keep your playbooks modular, making them easier to read, maintain, and reuse across multiple playbooks.


 
  
 