Definition

Why do we need pre_tasks, tasks, roles, post_tasks in Ansible?

In general, the order of execution will always be as follows:

  • 1) pre_tasks -> 2) roles -> 3) tasks -> 4) post_tasks

Main differences:

  • pre_tasks and post_tasks are needed to be used together with the roles directive to execute tasks before or after a role
  • roles and tasks share the same space and should not be used in the same play according to ansible best-practice

However, there is another important feature when working with handlers — within one play it can be called up to 3 times:

  1. in a pre_tasks
  2. in a roles/tasks (when used together, handler will be called at the end of tasks once)
  3. in a post_tasks

Also, it is important to note here that in pre_tasks and post_tasks you can call handlers from a role and it, according to the rule above, can be executed up to 3 times

Practice

Let’s write a simple playbook, role and config with the following structure:

├── ansible.cfg
├── roles
│   └── client
│       ├── handlers
│       │   └── main.yml
│       └── tasks
│           └── main.yml
└── test.yml

Content of ansible.cfg:

[defaults]
roles_path      = roles
stdout_callback = yaml

Content of roles/client/handlers/main.yml:

---
- name: Print role message
  ansible.builtin.debug:
    msg: Role handler executed succesfully

Content of roles/client/tasks/main.yml:

---
- name: Send role message
  ansible.builtin.command: /bin/true
  notify:
    - Print message
    - Print role message

Content of test.yml

---
- name: Testing handlers
  hosts: localhost
  gather_facts: false

  handlers:
    - name: Print message
      ansible.builtin.debug:
        msg: Handler executed succesfully

  pre_tasks:
    - name: Echo pre tasks
      ansible.builtin.command: /bin/true
      notify:
        - Print message
        - Print role message

  roles:
    - client

  tasks:
    - name: Echo tasks
      ansible.builtin.command: /bin/true
      notify:
        - Print message
        - Print role message

  post_tasks:
    - name: Post tasks
      ansible.builtin.command: /bin/true
      notify:
        - Print message
        - Print role message

Result of running ansible-playbook test.yml: Ansible_Tasks