I want to check that two variables are defined and not empty. I have a task debug
with that checks that and if either of the two variables are undefined or empty, it should fail the task. The problem is that, when both are defined, the script returns (correctly) that they are both defined, but the failed_when
condition still fails the task.
Here are my tasks:
- set_fact:
my_variable:
version: "2"
previous_version: "1"
- name: Ensure versions are present
ansible.builtin.debug:
msg: |
{% set missing_versions = [] %}
{% set version_names = ['version','previous_version'] %}
{% for version_name in version_names %}
{% if my_variable[version_name] is not defined or my_variable[version_name] == '' %}
{% set missing_versions = missing_versions + version_name %}
{% endif %}
{% endfor %}
{% if missing_versions | length > 0 %}
The following value(s) are missing: {{ missing_versions | join(', ') }}
{% else %}
The {{ version_names | join(', ') }} values are present.
{% endif %}
failed_when: missing_versions | length > 0
Expected result:
When my_variable.version
and my_variable.previous_version
are both defined:
The version, previous_version values are present.
Else:
The following value(s) are missing:
- version
- previous_version
As you can see in the set_fact
task, both of those values are defined, and when the debug
task runs it outputs "The version, previous_version values are present.", yet the task still fails. If I change the conditional to failed_when: no
, it succeeds. I even added text in the task to check the exact same conditional:
- name: Ensure versions are present
ansible.builtin.debug:
msg: |
{% set missing_versions = [] %}
{% set version_names = ['version','previous_version'] %}
{% for version_name in version_names %}
{% if my_variable[version_name] is not defined or my_variable[version_name] == '' %}
{% set missing_versions = missing_versions + version_name %}
{% endif %}
{% endfor %}
{% if missing_versions | length > 0 %}
The following value(s) are missing: {{ missing_versions | join(', ') }}
{% else %}
The {{ version_names | join(', ') }} values are present.
{% endif %}
Missing versions length > 0: {{ missing_versions | length > 0 }}
failed_when: missing_versions | length > 0
Result:
The version, previous_version values are present. \nMissing versions length > 0: False
So I know the conditional is correct, yet failed_when
is still failing the task even when the result is False
.
What am I missing? Also, I welcome any suggestions on improving my code to check that those two attributes aren't undefined/empty.
If you want to make a playbook fail for some reason(s) then, don't use a debug
task, rather use an assert
one:
- assert:
that:
- my_variable.version | default('') | length > 0
- my_variable.previous_version | default('') | length > 0
Using a default
, here, will ensure that the assertion will fail because of the condition defined and not with a failure of the assertion task itself.
The outcome of such a task would either be:
ok: [localhost] => changed=false
msg: All assertions passed
or
fatal: [localhost]: FAILED! => changed=false
assertion: my_variable.version | default('') | length > 0
evaluated_to: false
msg: Assertion failed
And you can further customise those as you're pleased with the success_msg
and failed_msg
parameters.