Let’s suppose I run a playbook as a non-root user and one task needs to include a vars file with only root permissions.
The ansible.builtin.include_vars official doc states that:the ‘become’ attribute is not supported but “Is usable alongside become keywords”, which seems to contradict the fact that it is unsupported.
I tried to use the become vars but that does not work either:
name: Including vars issue
hosts: all
gather_facts: false
tasks:
name: Including vars with root-only permissions
vars:
ansible_become: yes
ansible_become_method: sudo
ansible_become_user: root
include_vars: “…/files/restricted_file”
ignore_errors: true
name: Including vars with non-root user permissions
vars:
ansible_become: yes
ansible_become_method: sudo
ansible_become_user: admin
include_vars: “…/files/capabilities.json”
The “become” bits have to do with privilege escalation for Ansible tasks that run on the target hosts.
Including/importing vars and friends happen on the Ansible controller, not the target hosts.
It doesn’t matter that your target host and your Ansible controller are the same host. Controller bits aren’t privilege escalated.
Are you implying that it is not possible to include a vars file on the controller that require higher privileges than the user’s permissions running the playbook?
“Is usable alongside become keywords” is a description of the “becomes” attribute. The key point for your case is the red “none” in the “Support” column, which together means that no amount of “become” shenanigans is going to affect the behavior of include_vars.
Interpretation of the “Attributes” table is a bit obscure and error prone from users’ perspectives, IMHO. I believe it’s showing a peek under the covers of how modules are implemented. It appears there’s a fairly standard set of attributes, which are influenced by various keywords, config file settings, environment variables, and runtime conditions, and these attributes may influence to various degrees different aspects of modules’ operation. “Become” for example influences include_vars not at all.
Although your initial post amply demonstrates the problem you ran into, we can surmise that what you’re trying to accomplish is more interesting. Can we step back a bit and maybe up to a higher level and explore your actual use case? (I have a feeling the answer is going to involve ansible-vault. You’ve got me curious.)
The 'usable' part is badly phrased, it won't error (yet) with become
settings (from config/cli/keywords or vars) but it ignores them
Are you implying that it is not possible to include a vars file on the controller that require higher privileges than the user's permissions running the playbook?
This is exactly the case
One workaround, use a slurp task (with become) task to get the
original file and dump it into a variable (or a file and then
include_vars if you cannot use the container variable).
@uto…@gmail.com
I just need to let the user running the playbook access files which cannot be accessed to any other user (except root of course).I’m very surprised that this limitation exist with that module.
@Brian Coca
I just don’t understand why the ansible team has decided that become keywords cannot affect include_vars. It’s just a module that always runs on the controller, but what’s the difference with all other modules which are affected by become keywords but are delegated on the localhost? It just does not make any sense to me. Or maybe I’m missing a fundamental piece of the inner workings.
As to “why the ansible team has decided that become keywords cannot affect include_vars”, I rather doubt it’s ever come up before.
Internally, Ansible does lots of including/importing vars files. I imagine it evolved as a simple way to let the user pick some snowflake that wasn’t one of the 20 or so sources of variables that Ansible already pulled in. For reasons I don’t see, you’ve got an extraordinary quirk (root-only access) on an already unusual case.
Another approach you could try: Whatever rootly process that currently creates that file could end with an “ansible-vault encrypt …” operation on it (or a copy) that your controller process could be allowed to read. Or some variation on that theme.
I just don't understand why the ansible team has decided that become keywords cannot affect include_vars. It's just a module that always runs on the controller, but what's the difference with all other modules which are affected by become keywords but are delegated on the localhost? It just does not make any sense to me. Or maybe I'm missing a fundamental piece of the inner workings.
It was not as much a 'decision' as a 'consequence', include_vars is
NOT a module, it is an action plugin, both types work as 'task
actions' but action plugins execute inside the ansible process on the
controller while modules execute on a remote machine. We mostly hide
this distinction from the user but it creates several issues like
'become doesn't affect action plugins', also why we recently added
'attributes' to inform people of long standing behaviors that were not
noticed/ignored unless you hit a corner case like this.
So yes, you were missing a piece of the inner workings, one that was
purposefully hidden from users. 99% of the time this does not matter
much, but this case ended up being in the 1%.
one reason that this is an 'action' and not a module is that modules
are not allowed to change the normal variables, only 'return facts',
other actions like debug/includes/imports/add_host/group_by also
modify 'ansilbe internal data' which for many reasons, security being
just one, we don't allow modules to do.