How to specify ansible pretasks for a role?

DependenciesAnsibleRole

Dependencies Problem Overview


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?

Dependencies Solutions


Solution 1 - Dependencies

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 - Dependencies

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 3 - Dependencies

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 4 - Dependencies

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

Solution 5 - Dependencies

Just had to deal with the problem, the real issue is that the pre-task is very likely somewhat more specific than the role. Doing a post-task is easy, because you would simply make a new role dependant, this is known as a "wrapper role"... or at least that's what they call the idea in chef, for when your trying to extend something.

For a pre-task, you have to modify the hierarchy a bit, using a "wrapper role" and what I call a "sibling role". So the dependency logic would appear as,

  • wrapper role
  • sibling role
  • original role

The wrapper has two dependencies, but make sure to add the "sibling role" first in the dependency list. Since Ansible will go from top to bottom.

Finally, you should place your vars in the wrapper role, so that you could overwrite them from the playbook. You want the variables to follow the hierarchy, as much as possible, and not jump across the siblings.

Solution 6 - Dependencies

I have a similar need, and I solved it by defining the variable in the role vars. That is, creating a <role>/vars/main.yml with

---
user: proxy

that should override the user variable defined at apache module, while writing it in your module defaults directory doesn't.

I'm using ansible 1.9, not sure how long this behaviour has been present.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKęstutisView Question on Stackoverflow
Solution 1 - DependenciesChu-Siang LaiView Answer on Stackoverflow
Solution 2 - DependenciesudondanView Answer on Stackoverflow
Solution 3 - DependencieskimamulaView Answer on Stackoverflow
Solution 4 - DependenciesKashyapView Answer on Stackoverflow
Solution 5 - DependenciesJ. M. BeckerView Answer on Stackoverflow
Solution 6 - DependenciesJavier PalaciosView Answer on Stackoverflow