Note that service_public_ip did not get resolved as expected (even though facts were collected for that host already), and service_admin_ip works fine when I hardcode it and don’t use facts. Is there a way to get around this issue? I do not want to drop ansible_default_ipv4 stuff into the role’s playbook but prefer to keep it “configurable” with some sane default (default_ipv4). What am I missing in this?
P.S.
I have some other plays where group_vars/all.yml defines vars in similar fashion (referencing some of the facts) and those work just fine.
{% for h in groups['keystone'] %}
{% set myvars=hostvars[h] %}
{{ myvars.simple_var }}
{{ myvars.nested_var }}
{{ myvars.fact_var }}
{% endfor %}
-------
the playbook output is as expected - vars all rendered properly ,
however
templates are not so clean:
-------
Simple var
Simple var
192.168.0.138
Var extraction:
Simple var
{{simple_var}}
{{ansible_default_ipv4.address}}
-------
as you can see when iterating over hosts from the group for some reason
vars are not being resolved as expected.
The reason is: multiple layers of resolution are implemented as a magic dictionary that renders the variables on access. For some reason it explicitly ignores fancy dictionaries, and hostvars is one of those (it has some magic for caching).
I think it's a bug, but that should be decided by devs. Still, filling an issue should be OK
There was a ticket raised (possibly by you) recently that recursion in Jinja2 templates does not appear to be a thing. Since I think that’s filed already, we should be good to go, but I would consider this as something that should work.
As an alternative, if you put the variable name directly in the template, or use the “set_fact” module to assign the variable to a new name, you should be ok.
There was a ticket raised (possibly by you) recently that recursion in Jinja2 templates does not appear to be a thing. Since I think that’s filed already, we should be good to go, but I would consider this as something that should work.
yes, I did file a ticket ( https://github.com/ansible/ansible/issues/7799 ) as I was digging deeper into this issue it felt more and more like a bug, but I was hoping it was just me {ab,mis}using it.
As an alternative, if you put the variable name directly in the template, or use the “set_fact” module to assign the variable to a new name, you should be ok.
thanks for the tip - I did test this workaround and it works, albeit it puts quite a few extra items in a playbook to work around the issue. Just for posterity trick like that worked for me so far:
prepend to site.yml …
hosts: keystone
tasks:
set_fact: nested_var={{ nested_var }}
…
makes variable resolution inside Jinja template consistent with resolution in playbook. Ain’t pretty but it works.
Bonus question: can I write above statement using “with_items” so at least I don’t have to copy-paste entire stanza and only have to enumerate var names? (my guess is “no” but hey, maybe I’m wrong?)
“Bonus question: can I write above statement using “with_items” so at least I don’t have to copy-paste entire stanza and only have to enumerate var names? (my guess is “no” but hey, maybe I’m wrong?)”
This seems to be another topic, so let’s start a new thread on that, though seems easy for you to try first and maybe post if it’s not