How to use include_vars with a file needing elevated privileges

224 views
Skip to first unread message

jean-christophe manciot

unread,
Mar 17, 2022, 12:19:21 PM3/17/22
to Ansible Project
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: Creating a file with root-only permissions
                  vars:
                        ansible_become: yes
                        ansible_become_method: sudo
                        ansible_become_user: root
                  file:
                        group: 'root'
                        mode: '0640'
                        owner: 'root'
                        path: "../files/restricted_file"
                        state: touch

                - 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"
leads to:
         ___________________________________________________
        < TASK [Creating a file with root-only permissions] >
         ---------------------------------------------------
                \   ^__^
                 \  (oo)\_______
                    (__)\       )\/\
                        ||----w |
                        ||     ||

        changed: [localhost] => changed=true
          dest: ../files/restricted_file
          gid: 0
          group: root
          mode: '0640'
          owner: root
          size: 0
          state: file
          uid: 0
         __________________________________________________
        < TASK [Including vars with root-only permissions] >
         --------------------------------------------------
                \   ^__^
                 \  (oo)\_______
                    (__)\       )\/\
                        ||----w |
                        ||     ||

        fatal: [localhost]: FAILED! => changed=false
          ansible_facts: {}
          ansible_included_var_files: []
          message: 'an error occurred while trying to read the file ''playbooks/issues/../files/restricted_file'': [Errno 13] Permission denied: b''playbooks/files/restricted_file''. [Errno 13] Permission denied: b''playbooks/files/restricted_file'''
        ...ignoring
         ______________________________________________________
        < TASK [Including vars with non-root user permissions] >
         ------------------------------------------------------
                \   ^__^
                 \  (oo)\_______
                    (__)\       )\/\
                        ||----w |
                        ||     ||

        ok: [localhost] => changed=false
        ...

I'm probably missing something here; how can we work around this limitation?

jean-christophe manciot

unread,
Mar 17, 2022, 1:59:58 PM3/17/22
to Ansible Project
It seems to be a tricky one.
I am using ansible core 2.12.3.

Does @Brian Coca have any suggestion?

Todd Lewis

unread,
Mar 17, 2022, 2:59:23 PM3/17/22
to Ansible Project
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.

jean-christophe manciot

unread,
Mar 17, 2022, 3:02:56 PM3/17/22
to Ansible Project
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?

jean-christophe manciot

unread,
Mar 17, 2022, 3:04:29 PM3/17/22
to Ansible Project
Also, what does "Is usable alongside become keywords" mean?

Todd Lewis

unread,
Mar 17, 2022, 3:10:29 PM3/17/22
to Ansible Project
Yes, I implied exactly that. I should have stated it explicitly. (Also, I think it's true, but Ansible has surprised me more than once before.)

Todd Lewis

unread,
Mar 17, 2022, 3:21:30 PM3/17/22
to Ansible Project
"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.

Todd Lewis

unread,
Mar 17, 2022, 3:33:25 PM3/17/22
to Ansible Project
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.)

Brian Coca

unread,
Mar 17, 2022, 4:36:54 PM3/17/22
to Ansible Project
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).



----------
Brian Coca

jean-christophe manciot

unread,
Mar 17, 2022, 4:49:04 PM3/17/22
to Ansible Project
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.

Todd Lewis

unread,
Mar 17, 2022, 8:05:21 PM3/17/22
to ansible...@googlegroups.com

This slurp worked for me:

    - name: Slurp the file
      vars:
            ansible_become: yes
            ansible_become_method: sudo
            ansible_become_user: root
      slurp:
        src: "{{ restricted_file }}"
      delegate_to: "{{ controller_host }}"
      register: slop
        
    - name: Set a fact
      set_fact:
        slick: "{{ slop.content | b64decode | from_yaml }}"

I'm still curious, though, why there would be root-only vars files on your controller.

-- 
Todd

Todd Lewis

unread,
Mar 17, 2022, 8:22:20 PM3/17/22
to Ansible Project
 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.

Good luck!

Brian Coca

unread,
Mar 18, 2022, 4:20:04 PM3/18/22
to Ansible Project
@jean-chistophe manicot

> 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%.

--
----------
Brian Coca

Brian Coca

unread,
Mar 18, 2022, 4:21:49 PM3/18/22
to Ansible Project
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.



--
----------
Brian Coca

Reply all
Reply to author
Forward
0 new messages