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