Ansible: Conditionally define variables in vars file if a certain condition is met
Solution 1
What I did in the end was to create 2 separate var files - let's call them type_a.yml
and type_b.yml
- and I defined a group variable that indicates what file to use - something like type_of_file: a
. This is how my playbook looks now:
- name: blabla
hosts: blabla
vars_files:
- <path>/type_{{ type_of_file }}.yml
roles: blabla
Thanks for all the answers. I find them really helpful.
Solution 2
Ansible allows one of following forms to define variable conditionally:
test:
var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
var2: "{{'value' if (my_group_var) else 'other_value'}}"
Combining above syntax with vars lookup we can load complex vars (map in this case):
test_value_when_my_group_var_is_true:
var1: value
var2: value
test_value_when_my_group_var_is_false:
var1: other_value
var2: other_value
test: "{{ lookup('vars','test_value_when_my_group_var_is_true') if (my_group_var) else lookup('vars','test_value_when_my_group_var_is_false')}}"
There is another way of doing conditional tree loading with vars lookup. This way is handy when you need implement case logic (i.e. condition variable has more than two possible values):
test_value_when_my_group_var_is_foo:
var1: value
var2: value
test_value_when_my_group_var_is_bar:
var1: other_value
var2: other_value
test_value_when_my_group_var_is_baz:
var1: yet_another_value
var2: yet_another_value
test: "{{ lookup('vars','test_value_when_my_group_var_is_' + my_group_var) }}"
Solution 3
I don't think you can, I usually create separate files to hold conditional variable collections and use a when
clause to include them on a specific condition:
- include_vars: test_environment_vars.yml
when: global_platform == "test"
- include_vars: staging_environment_vars.yml
when: global_platform == "staging"
- include_vars: prod_environment_vars.yml
when:
- global_platform != "test"
- global_platform != "staging"
Solution 4
Despite it would be nice, I'm afraid that your way isn't possible (or I'm not aware right way).
I'd suggest to first prepare vars file from jinja template and then include it with include_vars. See the example playbook:
---
- name: -Test-
hosts: local
vars:
my_group_var: False
# my_group_var: True
tasks:
- name: Prepare vars file from template.
template: src=/tmp/vars.yaml.j2
dest=/tmp/vars.yaml
- name: Include vars
include_vars: "/tmp/vars.yaml"
The content of example jinja template /tmp/vars.yaml.j2 is:
{% if my_group_var %}
test:
var1: value
var2: value
{% else %}
test:
var1: other_value
var2: other_value
{% endif %}
Solution 5
Why no one mentions this?
_dist: "{{ ansible_lsb.id|lower if ansible_lsb.id == 'Raspbian' else ansible_distribution|lower }}"
Related videos on Youtube
pandoJohn
Updated on September 18, 2022Comments
-
pandoJohn over 1 year
Depending on the value(True/False) of a variable defined into the group_vars I am trying to define some variables in a vars file. Their value depends on the group var's value.
My current var file looks like this:
{% if my_group_var %} test: var1: value var2: value ... varn: value {% else %} test: var1: other_value var2: other_value ... varn: other_value {% endif %}
For each one of my roles I'm using a variable defined into this file.
My test playbook looks like below:
- name: blabla hosts: blabla vars_files: - <path>/test_vars.yml roles: blabla
The error I'm receiving after running the playbook is:
{% if my_group_var %} ^ here exception type: <class 'yaml.scanner.ScannerError'> exception: while scanning for the next token found character that cannot start any token in "<unicode string>"
Am I doing something stupid here or this is not even supported? I've tried to find another way for defining these vars(I have a lot of them) but I didn't managed to get something functional here. Any suggestions?
-
84104 about 6 yearsWhere do these vars end up being used? This might be unnecessary if all you're going to use them for is part of a
template
module call. -
Konstantin Suvorov about 6 yearsIf
test
is group dependent, it should be placed into group_vars. -
pandoJohn about 6 yearsUnfortunately, test is not group dependent. As mentioned in the description, test is depending on the value of a group_var variable.
-
-
pandoJohn about 6 yearsThis is something I was trying to avoid. I don't want to use include vars or to define 2 additional var files for my tasks.
-
pandoJohn about 6 yearsI like this but the problem is that after generating the .yml file from the jinja template this is not available for the subsequent tasks from my playbook.
-
Jaroslav Kucera about 6 yearsWhy? When I tried to extend the test playbook with debug task
- debug: var=test
I can see, that there are defined bothtest.var1
andtest.var2
with expected values. So you should be able to use these variables in other tasks of the playbook. -
GP92 about 5 yearsI don't get it..when it's possible to use include_vars with condition, why not variable can be defined with condition?
-
TRW over 3 yearsthis is in my eyes the best solution: divide and conquer.
-
Rajnish Kumar Soni almost 3 yearsI am new to ansible and this ans save lot of my effort. Thanks
-
Stan over 2 yearsThat last method of conditional logic worked perfectly for me. Thanks for the solution!