There was discussion during CfgMgmtCamp that it is not possible to have different messages for different conditions in one assert action with ansible.
I do not agree with that!
Here is the code:
- name: Different messages for different conditions in one asserts
hosts: localhost
gather_facts: false
vars:
one: true
two: false
tasks:
- name: Simple assert
ansible.builtin.assert:
that: conditions is ansible.builtin.all
fail_msg: "One of the conditions failed"
success_msg: "All of the conditions successful"
failed_when: false
vars:
conditions:
- "{{ one }}"
- "{{ two }}"
- name: Extended assert
ansible.builtin.assert:
that: extended_conditions | map(attribute='condition') is ansible.builtin.all
fail_msg: "Following conditions have failed: {{ extended_conditions | rejectattr('condition') | map(attribute='msg') | join('; ') }}"
success_msg: "Following conditions are succesful: {{ extended_conditions | selectattr('condition') | map(attribute='msg') | join('; ') }}"
failed_when: false
vars:
extended_conditions:
- msg: "message"
condition: "{{ one or two }}"
- msg: "this condition failed"
condition: "{{ two }}"
This code work with both ansible-core 2.20 and 2.16 (I’ve also checked other versions, here just for brevity)
bash-5.2$ uv run --with ansible-core==2.16.16 ansible-playbook playbook.yml
Installed 9 packages in 17ms
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Different messages for different conditions in one asserts] ***************************************************************************
TASK [Simple assert] ************************************************************************************************************************
ok: [localhost] => {
"assertion": "conditions is ansible.builtin.all",
"changed": false,
"evaluated_to": false,
"failed_when_result": false,
"msg": "One of the conditions failed"
}
TASK [Extended assert] **********************************************************************************************************************
ok: [localhost] => {
"assertion": "extended_conditions | map(attribute='condition') is ansible.builtin.all",
"changed": false,
"evaluated_to": false,
"failed_when_result": false,
"msg": "Following conditions have failed: this condition failed"
}
PLAY RECAP **********************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
bash-5.2$ uv run --with ansible-core==2.20.2 ansible-playbook playbook.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Different messages for different conditions in one asserts] ***************************************************************************
TASK [Simple assert] ************************************************************************************************************************
ok: [localhost] => {
"assertion": "conditions is ansible.builtin.all",
"changed": false,
"evaluated_to": false,
"failed_when_result": false,
"msg": "One of the conditions failed"
}
TASK [Extended assert] **********************************************************************************************************************
ok: [localhost] => {
"assertion": "extended_conditions | map(attribute='condition') is ansible.builtin.all",
"changed": false,
"evaluated_to": false,
"failed_when_result": false,
"msg": "Following conditions have failed: this condition failed"
}
PLAY RECAP **********************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
There are some caveats of course, if you look closely, each condition is evaluated as variable (inside double curly brackets), not as condition (with out any curly brackets):
extended_conditions:
- msg: "message"
condition: "{{ one or two }}"
- msg: "this condition failed"
condition: "{{ two }}"
But I am yet to see condition that cannot be written this way (as variable)