Search code examples
ansible

Ansible: how to preserve a variable data type at set_fact


The original value that I'm trying to set with Ansible set_fact is a string:

features/move: "true"

Here is a block of code to set the above value:

set_fact:
  my_var: "{{ (all_vars | from_yaml).metadata.annotations['features/move'] | default(omit) }}"

The value is being set as a boolean True as Ansible converts string to boolean by default (source: https://github.com/ansible/ansible/issues/11905).

I'd like to print the value preserving its original data type which is a string:

{% if my_var is defined %}
my_var: "{{ my_var | lower }}"
{% endif %}

Which will give me expected output as a string:

my_var: "true"

However, what if the original value is a boolean, like:

features/move: true

With the above logic it will be set as True, and then printed out as "true" which is not correct.

I have tried expanding my if condition to make it work for both cases above (string and boolean), like:

{% if my_var is defined and my_var is string %}
my_var: "{{ my_var | lower }}"
{% elif my_var is defined %}
my_var: {{ my_var | lower }}
{% endif %}

However, it always goes into elif as the variable data type has been already converted to boolean during the set_fact step.

Is there a way to preserve an original data type in Ansible during the set_fact step before Ansible converts it to boolean? Any advice is very appreciated.


Solution

  • ... as the variable data type has been already converted to boolean during the set_fact step.

    That's correct and the expected behavior.

    Is there a way to preserve an original data type in Ansible during the set_fact step

    Not in general or for all data types. According the documentation about set_fact module – Set host variable(s) and fact(s) it will become a string

    before Ansible converts it to boolean?

    or

    Some boolean values (yes, no, true, false) will always be converted to boolean type

    However,

    unless DEFAULT_JINJA2_NATIVE is enabled. This is done so the var=value booleans, otherwise it would only be able to create strings, but it also prevents using those values to create YAML strings. Using the setting will restrict k=v to strings, but will allow you to specify string or boolean in YAML.

    Documentation