pieterjanv
(Pieter Jan Visser)
November 13, 2024, 12:58pm
1
undef()
behaves unexpectedly when set to a dictionary member. I expected the following code to ensure that more or less foo == {}
.
- hosts: localhost
gather_facts: no
vars:
foo:
bar: baz
tasks:
- vars:
foo:
bar: "{{ undef() }}"
debug:
var: foo
gives:
PLAY [localhost] ******************
TASK [debug] *****************
ok: [localhost] => {
"foo": "VARIABLE IS NOT DEFINED!"
}
Is this supposed to happen? The documentation does not help in this regard, and I have found no mention of the function in the docs of jinja2.
This is the expected behaviour. You have only partially defined the dictionary (at least one value is undefined, because you have explicitly set it to an undefined value) so it is treated as undefined
If, as you’ve stated, you want foo
to be equal to {}
, you should just do foo: {}
.
pieterjanv
(Pieter Jan Visser)
November 13, 2024, 3:03pm
3
I see. In this case there is a trivial alternative as you point out, but not when I’m trying to undefine a particular member of a dictionary.
Is there any expression in place of ???
that would unset foo.k2
, but leave any other keys intact?
- hosts: localhost
gather_facts: no
vars:
foo:
k1: v1
k2: v2
tasks:
- vars:
foo: "{{ ??? }}" # should unset foo.k2
debug:
var: foo
Being explicit about which keys to carry over does not work in the obvious way, because of lazy evaluation:
- vars:
foo:
k1: "{{ foo.k1 }}" # recursion error
pieterjanv
(Pieter Jan Visser)
November 15, 2024, 6:33pm
5
Thanks. First time encountering that filter, but applying it in the obvious way would result in a recursion error:
- hosts: localhost
gather_facts: no
vars:
foo:
k1: v1
k2: v2
tasks:
- vars:
foo: "{{ foo | ansible.utils.keep_keys(target=['k1']) }}"
debug:
var: foo # recursion error
I think working around the recursion depends on the rest of your playbook/use case. Heres one solution
- hosts: localhost
gather_facts: no
vars:
_foo:
k1: v1
k2: v2
foo: "{{ _foo }}"
tasks:
- vars:
foo: "{{ _foo | ansible.utils.keep_keys(target=['k1']) }}"
debug:
var: foo
pieterjanv
(Pieter Jan Visser)
November 15, 2024, 7:36pm
7
Perhaps this or evaluating something using set_fact to reassign the actual value will get you out of most situations, but it feels tedious. But I suppose that’s more about how to elegantly work around the (to me unexpected) properties of lazy evaluation, which is for another topic. Thanks.