Ansible: playbook calling Role in a directory that is in the roles directory

Eddie picture Eddie · May 20, 2016 · Viewed 25.8k times · Source

I would like to shape my directory structure of my ansible roles and playbooks.

Currently I have a directory structure like.

group_vars
    * all 
    * group-one
        - group-vars.yml
        - group-vault.yml
    ...
host_vars
  - server1.yml
plays
    - java_plays
       * deploy_fun_java_stuff.yml
    * deploy_playbook.yml
roles
    - role1 
            - tasks
               * main.yml
            - handlers 
            - (the rest of the needed directories)
    - role2
    - java 
        - java_role1
            - tasks
               * main.yml
            - handlers 
            - (the rest of the needed directories)

I would like to be able to call upon the role java_role1 in the play deploy_fun_java_stuff.yml

I can call

 ---
 - name: deploy fun java stuff
   hosts: java
   roles:
    - { role: role1 }

but I cannot call (I've tried multiple ways). Is this possible?


 - name: deploy fun java stuff
   hosts: java
   roles:
    - { role: java/java_role1 }

What I really want to accomplish is to be able to structure my plays in an orderly fashion along with my roles. I will end up with a large number of both roles and plays I would like to organize them.

I can handle this with a separate ansible.cfg file for each play directory but I cannot add those cfg files to ansible tower (So I'm looking for an alternate solution).

Answer

fishi0x01 picture fishi0x01 · May 21, 2016

I think the problem is that you need to set the relative path properly. Ansible first applies the given path relative to the called playbooks directory, then looks in the current working path (from which you are executing the ansible-playbook command) and finally checks in /etc/ansible/roles, so instead of { role: java/java_role1 } in your dir structure you could use { role: ../../roles/java/java_role1 } or { role: roles/java/java_role1 }. Yet another option would be to configure the paths in which ansible is looking for roles. For that you could set the roles_path inside your projects ansible.cfg as described in the Ansible docs.

Based on your example:

Dir tree:

ansible/
├── hosts
│   └── dev
├── plays
│   └── java_plays
│       └── java.yml
└── roles
    ├── java
    │   └── java_role1
    │       └── tasks
    │           └── main.yml
    └── role1
        └── tasks
            └── main.yml

To test it, the play would include java_role1 and role1.

plays/java_plays/java.yml:

---
 - name: deploy java stuff
   hosts: java
   roles:
    - { role: roles/role1 }
    - { role: roles/java/java_role1 }

For testing purposes these roles simply print a debug msg.

role1/tasks/main.yml:

---
- debug: msg="Inside role1"

The dev hosts file simply sets localhost to the java group. Now I can use the playbook:

fishi@zeus:~/workspace/ansible$ ansible-playbook -i hosts/dev plays/java_plays/java.yml

PLAY [deploy java stuff] *******************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [role1 : debug] ***********************************************
ok: [localhost] => {
    "msg": "Inside role1"
}

TASK [java_role1 : debug] *************************************
ok: [localhost] => {
    "msg": "Inside java_role1"
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0

Now doing the same when you use { role: ../../roles/java/java_role1 } and { role: ../../roles/role1 } your log output inside the TASK brackets would show the whole relative path instead of just the role name:

fishi@zeus:~/workspace/ansible$ ansible-playbook -i hosts/dev plays/java_plays/java.yml

PLAY [deploy java stuff] *******************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [../../roles/role1 : debug] ***********************************************
ok: [localhost] => {
    "msg": "Inside role1"
}

TASK [../../roles/java/java_role1 : debug] *************************************
ok: [localhost] => {
    "msg": "Inside java_role1"
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0