Andy_Wang
(Andy Wang)
April 8, 2019, 7:40pm
1
I have a playbook that checks the existence of a local fact, but not every hosts have this local fact.
On servers where it does not exist my playbook fails with:
“msg”: "The conditional check ‘ansible_local[‘my_fact’][‘default’][‘name’] is defined’ failed. The error was: error while evaluating conditional (ansible_local[‘my_fact’][‘default’][‘name’] is defined): ‘dict object’ has no attribute ‘my_fact’
This is quite annoying. I think I can work around it by checking the existence of the local fact file, but it feels like I’m missing something obvious.
You need to use the default filter
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#defaulting-undefined-variables
And you need to use the filter on every sub attribute.
So something like this should work
((ansible_local['my_fact'] | default({}))['default'] | default({}))['name'] | default({})
system
(system)
April 9, 2019, 1:30pm
3
or a more flexible conditional:
when: "'my_fact' in ansible_local and
ansible_local['my_fact']['default']['name'] is defined"
FYI, in newer version of Ansilbe, `ansible_local` is always defined,
even if empty, so no need to use default on it
Andy_Wang
(Andy Wang)
April 10, 2019, 2:32pm
4
Sadly, neither the suggested solutions worked. I’m using Ansible 2.5.2 BTW.
Andy_Wang
(Andy Wang)
April 10, 2019, 7:36pm
5
The workaround I came up with was:
name: Check if local fact exists
stat:
path: /etc/ansible/facts.d/my_fact.fact
register: local_fact
name: Create empty local fact
ini_file:
path: /etc/ansible/facts.d/my_fact.fact
section: “default”
option: “{{ item.option }}”
value: “{{ item.value }}”
with_items:
{ option: “name”, value: “” }
{ option: “key”, value: “” }
when: local_fact.stat.exists == False
name: read local facts
setup:
filter=ansible_local
or a more flexible conditional:
when: "'my_fact' in ansible_local and
ansible_local['my_fact']['default']['name'] is defined"
To OP you might need to add is defined on ansible_local['my_fact']['default'] too, depending on you variables.
FYI, in newer version of Ansilbe, `ansible_local` is always defined,
even if empty, so no need to use default on it
FYI, I did not use default on ansible_local, only my_fact, default and name.