Ansible is a powerful automation tool that simplifies configuration management and application deployment. One of its key features is the ability to structure and reuse tasks across multiple playbooks, reducing repetition and enhancing modularity. This is made possible through the include_tasks
module, which allows you to include external task files dynamically.
In this article, we will explore how to use the include_tasks module effectively.
Why Use include_tasks in Ansible?
The include_tasks
module enables dynamic inclusion of tasks from external files during playbook execution. This offers several benefits:
Reusability
: Avoid duplication by creating task files that can be reused across multiple playbooks.Modularity
: Break down large playbooks into smaller, manageable components for better organization.Dynamic Execution
: Include task files based on conditions, variables, or runtime decisions.Improved Readability
: Keep playbooks concise and readable by offloading tasks to external files.
For example, if you are managing different tasks for installing software, updating systems, or configuring users, these tasks can be separated into their own files. This structure makes troubleshooting and updates easier.
Basic syntax of include_tasks
The syntax for including a task file is simple. Here’s a basic example:
- name: Include external task file
include_tasks: path/to/task_file.yml
The include_tasks
directive points to the path of the task file relative to the playbook or role. This tells Ansible to load and execute the tasks defined in the specified file during playbook execution.
Now, let’s dive deep to understand how to include tasks in Ansible.
1. Creating a task file
A task file is a YAML file containing a list of tasks. It is structured just like the tasks
section in a playbook but without the hosts
or vars
declarations.
Let’s create a task file called common_tasks.yml
inside the tasks directory to perform basic server setup:
---
- name: Ensure the system is up to date
apt:
update_cache: yes
- name: Install NGINX
apt:
name: nginx
state: present
In this example:
- The first task ensures the system’s package cache is updated.
- The second task installs NGINX on the target system.
You can reuse the above file across multiple playbooks instead of duplicating these tasks.
2. Including the task file in a playbook
You can include the task file in your main playbook using the include_tasks
directive.
Here is the main playbook.yml
:
---
- hosts: web_servers
become: true
tasks:
- name: Include common tasks
include_tasks: tasks/common_tasks.yml
In the above playbook:
- The
include_tasks
directive points to the external task file (common_tasks.yml). - The
hosts
section specifies that these tasks will run on the web_servers group. - The
become: true
statement ensures tasks requiring elevated privileges are executed as a superuser.
When you run the above playbook Ansible dynamically loads and executes the tasks defined in common_tasks.yml
.
3. Using include_tasks with variables
To make task files more versatile, you can pass variables when including tasks. This approach allows the same task file to handle different scenarios.
First, create a install_packages.yml
inside the tasks
directory.
---
- name: Install a package
apt:
name: "{{ package_name }}"
state: present
Next, create a main playbook:
---
- hosts: web_servers
become: true
vars:
package_name: nginx
tasks:
- name: Include task with variables
include_tasks: tasks/install_packages.yml
In this playbook:
- The variable
package_name
is defined in thevars
section of the playbook. - This variable is passed to the
tasks/install_packages.yml
file and replaces{{ package_name }}
dynamically.
When you run the above playbook Ansible will install the package specified by the package_name
variable.
4. Conditional task inclusion
Sometimes, you only want to include certain tasks based on specific conditions. The when
clause lets you include task files dynamically based on runtime variables.
Here is the example playbook:
---
- hosts: web_servers
become: true
vars:
install_nginx: true
tasks:
- name: Conditionally include tasks
include_tasks: tasks/install_packages.yml
when: install_nginx
In this playbook:
- The
when
clause evaluates the variable install_nginx. - If
install_nginx
istrue
, the tasks ininstall_packages.yml
are included and executed. Otherwise, they are skipped.
This method is helpful for scenarios where certain tasks depend on user input or environmental factors.
5. Using include_tasks with loops
The include_tasks
module can also be used in a loop
to include multiple task files dynamically. This is useful for OS-specific or environment-specific configurations.
Here is the directory structure of tasks:
tasks/
setup_ubuntu.yml
setup_centos.yml
And, the main playbook is:
---
- hosts: all
become: true
tasks:
- name: Include OS-specific tasks
include_tasks: "tasks/setup_{{ ansible_os_family | lower }}.yml"
In this example:
- The
ansible_os_family
fact is dynamically resolved for each target host. - Ansible includes the appropriate task file based on the OS family (e.g.,
Ubuntu
orCentOS
).
Conclusion
The include_tasks module in Ansible is a handy tool for creating modular and reusable playbooks. By splitting tasks into smaller files and including them as needed, you can improve the readability, maintainability, and scalability of your automation workflows.
✍️
Author: Hitesh Jethwa has more than 15+ years of experience with Linux system administration and DevOps. He likes to explain complicated topics in easy to understand way.