Fragmenting Ansible Playbooks

Importing

Importing Tasks or Handlers

From bib. source

We’ve already seen one of the most basic ways of including other files. […], when vars_files was used to place variables into a separate […] file […]. […] Tasks can also be included in a similar way. In the tasks: section of your playbook, you can add import_tasks directives […]

That is to say, by adding the import_tasks field or directive to the tasks section, i.e. under the tasks field of a playbook or play, one can specify a YAML file path value (Geerling 2023, 123-124):

tasks:
  - import_tasks: imported-tasks.yml

Meanwhile, in the target YAML file, a flat list of tasks is included (“flat¨ insofar as all at the top-level of the YAML file) (Geerling 2023, 124):

---
- name: Add profile info for user.
  copy:
    src: example_profile
    dest: "/home/{{ username }}/.profile"
    owner: "{{ username }}"
    group: "{{ username }}"
    mode: 0744
 
- name: Add private keys for user.
  copy:
    src: "{{ item.src }}"
    dest: "/home/{{ username }}/.ssh/{{ item.dest }}"
    owner: "{{ username }}"
    group: "{{ username }}"
    mode: 0600
  with_items: "{{ ssh_private_keys }}"
 
- name: Restart example service.
  service:
    name: example
    state: restarted

When this task file is imported into our playbook, it runs once before the Ansible playbook is executed (Geerling 2023, 126). This is important to keep in mind in case the imported file depends on some state effectuated at some point in the execution of the playbook–it may well fail or throw an error in that situation (Ibid). Since handlers in Ansible are “glorified tasks¨ (Geerling 2023, 127):

From bib. source

Handlers can be imported or included just like tasks, within a playbook’s handlers section.

The following exemplifies this (Ibid):

handlers:
  - import_tasks: handlers.yml

Importing Playbooks

In addition, Ansible playbooks can be imported into other playbooks, as a YAML file path value for the field import_playbook (Geerling 2023, 128). That being said, they cannot be included like tasks, which means that each playbook’s execution should be treated as sequential but self-contained (Ibid). Furthermore, an example use-case is that (Ibid):

From bib. source

[…], you can create playbooks to configure all the servers in your infrastructure then create a master playbook that includes each of the individual playbooks. […], you can run one ansible-playbook command!

Including

Including Tasks or Handlers

Just as with task imports there is a field that takes a YAML file path with tasks, albeit in this case that field is include_tasks; yet, the usefulness of this alternate field is that it can occur at any point in the state changes of the playbook execution (Geerling 2023, 126-127):

From bib. source

Ansible 2.0 and later evaluates includes during playbook execution, […]

In addition, since handlers in Ansible are “glorified tasks¨ (Geerling 2023, 127):

From bib. source

Handlers can be imported or included just like tasks, within a playbook’s handlers section.

This can be exemplified as follows:

handlers:
  - include_tasks: handlers.yml

Variables for imports / includes

Variables in included or imported YAML files allow that YAML file to be reusable in different scenarios (Geerling 2023, 125).

file_path YAML_Aint_Markup_Language Yet_Another_Markup_Language lists variable configuration_management handler


bibliography

  • “Playbook Organization - Roles, Includes, and Imports.” In Ansible for DevOps: Server and Configuration Management for Humans, 2nd ed., 123–147. Leanpub, 2023.