11

We broke down our giant ansible workspace into individual, simple roles that can be run on their own. They all depend on our yum role that provisions repositories, etc, and all the roles (A, B, C) have it listed in their meta.yml:

./roles_galaxy/A/meta/main.yml:
dependencies:
  - name: yum-repo
    src: foo

./roles_galaxy/B/meta/main.yml:
dependencies:
  - name: yum-repo
    src: foo

./roles_galaxy/C/meta/main.yml:
dependencies:
  - name: yum-repo
    src: foo

However, this causes the yum-repo role to be executed multiple times when our deploy playbook is run, so we see multiple executions of the yum-repo role. We don't want it to do this, as it just takes up extra time and runs repeatedly:

Playbook:

- name: Common Roles
  hosts: things
  roles:
    - A
    - B
    - C

Output:

PLAY [Role A] 
...
TASK [yum-repo ...]

PLAY [Role B] 
...
TASK [yum-repo ...]

PLAY [Role C] 
...
TASK [yum-repo ...]

I've tried allow_duplicates = false in our ansible.cfg, but I don't think that's the right solution as it still executes multiple times.

If there's more information needed, I'm more than happy to try to provide a cleaned up version of it. Running ansible-2.5.5 currently.

  • Are you using `import_role` or `include_role`? If so, see [Include_role loop installs role and dependencies multiple times](https://github.com/ansible/ansible/issues/56046). – colan Jul 30 '19 at 21:45
  • Are there different tags applied to roles A/B/C? "Ansible only executes role dependencies once, even if defined multiple times, unless the **parameters, tags, or when clause** defined on the role are different for each definition." – PolyTekPatrick Jan 21 '22 at 01:21

4 Answers4

3

Assuming you're using import_role and/or include_role, until Include_role loop installs role and dependencies multiple times gets fixed, I'd recommend the following:

  1. Don't specify your dependent roles as dependencies.
  2. Only specify them in calls to import_role and/or include_role.
colan
  • 2,818
  • 2
  • 20
  • 17
  • This is also fix to prevent role decencies to execute before role tasks due to the role exec rule: - Any role dependencies defined in the roles meta/main.yml will be run first, subject to tag filtering and conditionals. see http://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html?#using-roles – Max Barrass Sep 26 '19 at 01:37
1

And over a year later, ansible duplicate detection is still broken.

I set an ansible fact, and then in other roles, use

- name: include dependancy role
  include_role:
    name: somerole
  when: has_it_run_fact is not defined
0

Checkout the docs which cover this subject (Role Duplication and Execution).

Ansible strives to go for the most efficient approach, and avoid running a role any more than once, unless any params it uses, are different for each time it is declared in your play. Is it the case that each time your yum role runs, it is configuring a different yum repo?

Not sure how relevant it would be in the case of a Yum role, however one possible strategy is to split out the common, one off stuff into a separate role, and then make the common role a dependency of the main role. This results in a common role that is applied once, and then any number of invocations of the main role for each difference in params.

clockworknet
  • 2,736
  • 1
  • 15
  • 19
  • _Is it the case that each time your yum role runs, it is configuring a different yum repo?_ Nope, it's configured to run without any variables, i.e. all of our roles that call on the `yum-repo` role have the exact same thing listed in `meta/main.yml`. I tried appending `allow_duplicates: false` to all the `meta.yml` files, and that didn't change anything unfortunately. –  Jan 23 '19 at 18:53
0

use register variable whenever you run a playbook

something like

  • name: Perform first-time setup

    role: abc

    register: role_abc_var

    changed_when: "'abc Setup already performed' not in role_abc_var.stdout"

for clear explanation see
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html

cognitive
  • 31
  • 3