Ansible, running role multiple times with different parameter sets

There's limitations in the Ansible docs when it comes to this kind of thing - if there's an official best practice, I haven't come across it.

One good way that keeps your playbooks nice and readable is running several different plays against the host and calling the role with different parameters in each.

The role: foo, var: blah syntax shown a little way into this description is a good way to pass parameters in, and keeps it clear at a glance what is going on. For example:

- name: Run the docker role with docker_container_state=foo
  hosts: docker-host
  roles:
  - { role: docker_container, docker_container_state: foo }

- name: Run the docker role with docker_container_state=bar
  hosts: docker-host
  roles:
  - { role: docker_container, docker_container_state: bar }

In case you need the following information,

Sometimes, passing arguments to an Ansible role is an artificial way to run it multiple times effectively.

A typical use case is to restart an application several times, in the same playbook, in the process of installing it, with a different configuration each time. By Default, Ansible will consider that the restarting role has already been played and will not replay it. This must have something to do with idempotence.

The solution is to add the following property to the meta/main.yml of the role to be executed multiple times:

allow_duplicates: true

and you're good to go!


I usually use includes to run part of the role (or a whole role!) multiple times, if i have a decent layout of variables. See the example playbook below, with role apply_state which has print_state.yml inside roles/apply_state/tasks folder. The trick is to pass item inside include, after that it's a piece of cake.

playbook.yml

- hosts: localhost
  roles:
    - { role: apply_state, states: [ state_one, state_two, state_three ] }

roles/apply_state/tasks/main.yml

- name: print all states!
  include: print_state.yml state="{{ item }}"
  with_items: "{{ states }}" 

roles/apply_state/tasks/print_state.yml

- name: echo state
  debug: msg="{{ state }}"

See the output of ansible-playbook -i localhost, playbook.yml below:

PLAY [localhost] ***************************************************************

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

TASK [apply_state : print all states!] *****************************************
included: /home/user/roles/apply_state/tasks/print_state.yml for localhost
included: /home/user/roles/apply_state/tasks/print_state.yml for localhost
included: /home/user/roles/apply_state/tasks/print_state.yml for localhost

TASK [apply_state : echo state] ************************************************
ok: [localhost] => {
    "msg": "state_one"                                                                                                                 
}                                                                                                                                      

TASK [apply_state : echo state] ************************************************
ok: [localhost] => {
    "msg": "state_two"                                                                                                                 
}                                                                                                                                      

TASK [apply_state : echo state] ************************************************
ok: [localhost] => {
    "msg": "state_three"                                                                                                               
}                                                                                                                                      

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