<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">role</p>
<h5 dir="auto">ANSIBLE VERSION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.4.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/whitequark/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170118]"><pre class="notranslate"><code class="notranslate">ansible 2.4.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/whitequark/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170118]
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">Default.</p>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">N/A.</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">If roles B and C depend on role A, which has at least one task that executes, role A is ran only one time. If all tasks in A are skipped, role A is ran (as visible on stdout) three times.</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./roles/x/tasks/main.yml
- name: foo
  debug: msg='x called'
  when: false
# ./roles/z/meta/main.yml
dependencies:
- { name: 'x' }
# ./roles/z/tasks/main.yml
- debug: msg='z called'
# ./roles/y/meta/main.yml
dependencies:
- { name: 'x' }
# ./roles/y/tasks/main.yml
- debug: msg='y called'
# ./localhost.yml
---
- hosts: localhost
  roles:
  - { name: 'x' }
  - { name: 'y' }
  - { name: 'z' }"><pre class="notranslate"><span class="pl-c"><span class="pl-c">#</span> ./roles/x/tasks/main.yml</span>
- <span class="pl-ent">name</span>: <span class="pl-s">foo</span>
  <span class="pl-ent">debug</span>: <span class="pl-s">msg='x called'</span>
  <span class="pl-ent">when</span>: <span class="pl-c1">false</span>
<span class="pl-c"><span class="pl-c">#</span> ./roles/z/meta/main.yml</span>
<span class="pl-ent">dependencies</span>:
- <span class="pl-s">{ name: 'x' }</span>
<span class="pl-c"><span class="pl-c">#</span> ./roles/z/tasks/main.yml</span>
- <span class="pl-ent">debug</span>: <span class="pl-s">msg='z called'</span>
<span class="pl-c"><span class="pl-c">#</span> ./roles/y/meta/main.yml</span>
<span class="pl-ent">dependencies</span>:
- <span class="pl-s">{ name: 'x' }</span>
<span class="pl-c"><span class="pl-c">#</span> ./roles/y/tasks/main.yml</span>
- <span class="pl-ent">debug</span>: <span class="pl-s">msg='y called'</span>
<span class="pl-c"><span class="pl-c">#</span> ./localhost.yml</span>
---
- <span class="pl-ent">hosts</span>: <span class="pl-s">localhost</span>
  <span class="pl-ent">roles</span>:
  - <span class="pl-s">{ name: 'x' }</span>
  - <span class="pl-s">{ name: 'y' }</span>
  - <span class="pl-s">{ name: 'z' }</span></pre></div>
<p dir="auto">or as a <a href="https://github.com/ansible/ansible/files/1385264/bug.zip">zip archive</a></p>
<h5 dir="auto">EXPECTED RESULTS</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [y : debug] ***************************************************************
ok: [localhost] =&gt; {
    &quot;msg&quot;: &quot;y called&quot;
}

TASK [z : debug] ***************************************************************
ok: [localhost] =&gt; {
    &quot;msg&quot;: &quot;z called&quot;
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   "><pre class="notranslate"><code class="notranslate">PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [y : debug] ***************************************************************
ok: [localhost] =&gt; {
    "msg": "y called"
}

TASK [z : debug] ***************************************************************
ok: [localhost] =&gt; {
    "msg": "z called"
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   
</code></pre></div>
<h5 dir="auto">ACTUAL RESULTS</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [y : debug] ***************************************************************
ok: [localhost] =&gt; {
    &quot;msg&quot;: &quot;y called&quot;
}

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [z : debug] ***************************************************************
ok: [localhost] =&gt; {
    &quot;msg&quot;: &quot;z called&quot;
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   "><pre class="notranslate"><code class="notranslate">PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [y : debug] ***************************************************************
ok: [localhost] =&gt; {
    "msg": "y called"
}

TASK [x : foo] *****************************************************************
skipping: [localhost]

TASK [z : debug] ***************************************************************
ok: [localhost] =&gt; {
    "msg": "z called"
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   
</code></pre></div>
<p dir="auto">Per tomkmem on IRC</p>
<p dir="auto">mpdehaan: definately a bug then, i just dumped the list of {{ groups.all }} and it contains all the dupes</p>
<p dir="auto">So add a host to more than one group and it may in a group more than once, or maybe the groups list is just wrong and needs to be given a set([]) operation.</p>