Role Dependency Not Being Executed

Hi I have run into an issue where I’m not sure if it’s a bug in Ansible or just my lack of understand how roles are activated. Using Ansible 1.7.2, I have a playbook defined as such:

app/site.yml
app/roles/core/tasks/main.yml
app/roles/app-common/tasks/main.yml
app/roles/app-compA/meta/main.yml → contains a dependency on app-common

app/roles/app-compA/tasks/main.yml
app/roles/app-compB/meta/main.yml → contains a dependency on app-common

app/roles/app-compB/tasks/main.yml

Where site.yml activates roles like such:

  • hosts: all
    vars:
    home: /usr/local/app
    release: “{{ lookup(‘env’,‘RELEASE’) }}”
    group: “{{ lookup(‘env’,‘GROUP’) }}”

roles:

  • core

Component Specific Stuff

  • { role: app-compA, when: group== ‘compA’ }

  • { role: app-compB, when: group== ‘compB’ }

When I run the playbook like so:
export GROUP=compA
ansible-playbook site.yml -c local

The roles core, app-common & app-compA execute like expected.

However when I run the playbook like so:
export GROUP=compB
ansible-playbook site.yml -c local

Only the roles core and app-compB are executed and the app-common role is not executed. Shouldn’t the app-common role also be executed in this case? Is this a bug or have I mis-understood how roles are executed when role dependencies exists? My intent was to minimize the duplication of the tasks defined in app-common that are required by the app-compA & app-compB roles, so if there is another way to do this I’m all ears.

Thanks

Hard to see with the way it’s written above, do you perhaps have a bare-minimum repo to share?

Here you go.

https://github.com/jmal98/ansible-role-dep-example

My test env:

root@01e437db9a4c:/role-execution# ansible --version
ansible 1.7.2

root@01e437db9a4c:/role-execution# export GROUP=compA
root@01e437db9a4c:/role-execution# ansible-playbook site.yml -c local

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [core | Do some common work] ********************************************
ok: [127.0.0.1] => {
“msg”: “Did some common work.”
}

TASK: [app-common | Do some app-common work] **********************************
ok: [127.0.0.1] => {
“msg”: “Did some app-common work.”
}

TASK: [app-compA | Do some app-compA work] ************************************
ok: [127.0.0.1] => {
“msg”: “Did some app-compA work.”
}

TASK: [app-compB | Do some app-compB work] ************************************
skipping: [127.0.0.1]

PLAY RECAP ********************************************************************
127.0.0.1 : ok=4 changed=0 unreachable=0 failed=0

root@01e437db9a4c:/role-execution# export GROUP=compB
root@01e437db9a4c:/role-execution# ansible-playbook site.yml -c local

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [core | Do some common work] ********************************************
ok: [127.0.0.1] => {
“msg”: “Did some common work.”
}

TASK: [app-common | Do some app-common work] **********************************
skipping: [127.0.0.1]

TASK: [app-compA | Do some app-compA work] ************************************
skipping: [127.0.0.1]

TASK: [app-compB | Do some app-compB work] ************************************
ok: [127.0.0.1] => {
“msg”: “Did some app-compB work.”
}

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

Hi Jamal,

We actually have an open issue for this currently: https://github.com/ansible/ansible/issues/9292. For now the work-around is to avoid the “diamond” pattern for roles, where the dependent roles with multiple parents use conditionals or tags.

Thanks!

Ok.

Thanks

Is it possible to use multiple conditions to activate a role?

e.g.)

  • { role: app-compA, when: group== ‘compA’ or group== ‘compB’ }

It should, yes. I just tested in your sample repo -- removing the
dependencies for compA and compB and then adding a new role for
app-common:

- { role: app-common, when: group == 'compA' or group == 'compB' }

Worked as I expected; app-common was run when GROUP was either compA
or compB but was skipped for other values of GROUP.

-Toshio

Yeah, I realized that I could try it shortly after firing off this email.

Thanks