I have an Ansible task which loops through a list and for each item in the list runs a role, using include_role
. For each iteration of loop I want to pass a different set of variables. Currently, I am trying to do this by creating the list as a list of dictionaries which can be specified using --extra-vars
at runtime.
For example, I have task:
- name: Run the test role
include_role:
name: test_role
loop: '{{ input_list }}'
And the input_list
:
input_list:
- var1: foo
var2: bar
var3: baz
- var1: hello
var3: world
But at this point how would I go about passing the current set of variables to the role? I initially tried defining each variable separately:
- name: Run the test role
include_role:
name: test_role
vars:
var1: '{{ item.var1 }}'
var2: '{{ item.var2 }}'
var3: '{{ item.var3 }}'
loop: '{{ input_list }}'
This works, but if one variable is missing from the input_list
(i.e. should fall back to default value specified in the role defaults or at the start of the playbook for that variable) the play will fail.
So I tried using Jinja2's default
filter:
- name: Run the test role
include_role:
name: test_role
vars:
var1: '{{ item.var1 | default('foo') }}'
var2: '{{ item.var2 | default('bar') }}'
var3: '{{ item.var3 | default('baz') }}'
loop: '{{ input_list }}'
Again, this works, but it is a bit messy as every variable needs to be defined, and it doesn't use the default values from the role. Is there a better way of doing something like this?
Best Answer
One of the options is to create alternative defaults. For example, create a minimal role for testing
The task
gives
Let's create alternative defaults, e.g.
and use it in the include. The task below gives the same result
Now, let's define the dictionary with the alternate defaults
gives
The next option is to create and use alternate vars
For example, the task below gives the same result. The only difference is the precedence.