Ansible, running role multiple times with different parameter sets

16,038

Solution 1

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 }

Solution 2

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

Solution 3

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!

Share:
16,038
vuliad
Author by

vuliad

Updated on June 15, 2022

Comments

  • vuliad
    vuliad almost 2 years

    What is the best practice for running one role with different set of parameters?

    I need to run one application(docker container) multiple times on one server with different environment variables for each.

  • woozymj
    woozymj almost 4 years
    Not sure if the above syntax is valid anymore. To pass single/multiple variables to different executions of a role, check Example 1 - passing different parameters: in this official doc reference: docs.ansible.com/ansible/latest/user_guide/….