How to specify ansible pretasks for a role?

How should one go about defining a pretask for role dependencies. I currently have an apache role that has a user variable so in my own role in <role>/meta/main.yml I do something like:

---
dependencies:
  - { role: apache, user: proxy }

The problem at this point is that I still don't have the user I specify and when the role tries to start apache server under a non existent user, I get an error.

I tried creating a task in <role>/tasks/main.yml like:

---
- user: name=proxy

But the user gets created only after running the apache task in dependencies (which is to be expected). So, is there a way to create a task that would create a user before running roles in dependencies?


Solution 1:

I use the pre_tasks to do some tasks before roles, thanks for Kashyap.

#!/usr/bin/env ansible-playbook

---
- hosts: all
  become: true
  pre_tasks:
    - name: start tasks and sent notifiaction to HipChat
      hipchat:
        color: purple
        token: "{{ hipchat_token }}"
        room: "{{ hipchat_room }}"
        msg: "[Start] Run 'foo/setup.yml' playbook on {{ ansible_nodename }}."

  roles:
    - chusiang.vim-and-vi-mode

  vars:
    ...

  tasks:
    - name: include main task
      include: tasks/main.yml

  post_tasks:
    - name: finish tasks and sent notifiaction to HipChat
      hipchat:
        color: green
        token: "{{ hipchat_token }}"
        room: "{{ hipchat_room }}"
        msg: "[Finish] Run 'foo/setup.yml' playbook on {{ ansible_nodename }}."

# vim:ft=ansible :

Solution 2:

As of Ansible 2.2, you can use include_role. https://docs.ansible.com/ansible/include_role_module.html

- user: name=proxy

- include_role:
    name: apache
  vars:
    user: proxy

Solution 3:

You could simply solve this with another dependency either in your unnamed <role> or in the apache role.

Whole content of a new proxy-user role:

---
- user: name=proxy
...

Then in roles/apache/meta/main.yml add a dependency to it.

---
dependencies:
  - proxy-user
...

Or set it in roles/<role>/meta/main.yml:

---
dependencies:
  - proxy-user
  - { role: apache, user: proxy }
...

Solution 4:

Short answer: I don't think the language allows specifying pre_tasks for roles.

You could cheat/work-around by moving creation of user to a separate playbook and includeing the playbook instead of role. Something like this:

my_fake_role_playbooks/user_and_apache.yml:

- hosts: "{{p_hosts}}"
  pre_tasks:
    user: name=proxy
  roles: [ apache ]

actual_playbook.yml:

- include: my_fake_role_playbooks/user_and_apache.yml p_hosts=[host1, host2]

* code is untested.

HTH