[openstack-dev] [tripleo] [tripleo-validations] using using top-level fact vars will deprecated in future Ansible versions

Sam Doran sdoran at redhat.com
Wed Jul 25 17:46:56 UTC 2018

I spoke with other Ansible Core devs to get some clarity on this change.

This is not a change that is being made quickly, lightly, or without a whole of bunch of reservation. In fact, that PR created by agaffney may not be merged any time soon. He just wanted to get something started and there is still ongoing discussion on that PR. It is definitely a WIP at this point.

The main reason for this change is that pretty much all of the Ansible CVEs to date came from "fact injection", meaning a fact that contains executable Python code Jinja will merrily exec(). Vars, hostvars, and facts are different in Ansible (yes, this is confusing — sorry). All vars go through a templating step. By copying facts to vars, it means facts get templated controller side which could lead to controller compromise if malicious code exists in facts.

We created an AnsibleUnsafe class to protect against this, but stopping the practice of injecting facts into vars would close the door completely. It also alleviates some name collisions if you set a hostvar that has the same name as a var. We have some methods that filter out certain variables, but keeping facts and vars in separate spaces is much cleaner.

This also does not change how hostvars set via set_fact are referenced. (set_fact should really be called set_host_var). Variables set with set_fact are not facts and are therefore not inside the ansible_facts dict. They are in the hostvars dict, which you can reference as {{ my_var }} or {{ hostvars['some-host']['my_var'] }} if you need to look it up from a different host.

All that being said, the setting to control this behavior as Emilien pointed out is inject_facts_as_vars, which defaults to True and will remain that way for the foreseeable future. I would not rush into changing all the fact references in playbooks. It can be a gradual process.

Setting inject_facts_as_vars to True means ansible_hostname becomes ansible_facts.hostname. You do not have to use the hostvars dictionary — that is for looking up facts about hosts other than the current host.

If you wanted to be proactive, you could start using the ansible_facts dictionary today since it is compatible with the default setting and will not affect others trying to use playbooks that reference ansible_facts.

In other words, with the default setting of True, you can use either ansible_hostname or ansible_facts.hostname. Changing it to False means only ansible_facts.hostname is defined.

> Like, really. I know we can't really have a word about that kind of decision, but... damn, WHY ?!

That is most certainly not the case. Ansible is developed in the open and we encourage community members to attend meetings <https://github.com/ansible/community/blob/master/meetings/README.md> and add topics to the agenda <https://github.com/ansible/community/issues/325> for discussion. Ansible also goes through a proposal process for major changes, which you can view here <https://github.com/ansible/proposals/issues?utf8=%E2%9C%93&q=is:issue+is:open>.

You can always go to #ansible-devel on Freenode or start a discussion on the mailing list <https://groups.google.com/forum/#!forum/ansible-devel> to speak with the Ansible Core devs about these things as well.



Sam Doran
Senior Software Engineer
Ansible by Red Hat
sdoran at redhat.com <mailto:sdoran at redhat.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20180725/a5e9f8a2/attachment.html>

More information about the OpenStack-dev mailing list