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 the vars 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 is true, the tasks in install_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 or CentOS).

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.

Similar Posts