Search code examples
sshansiblesudoansible-inventory

Ansible unable to create folder on localhost with different user


I'm executing ansible playbook with appuser whereas I wish to create folder with user webuser on localhost.

ssh keys are setup for webuser on my localhost. So after login with appuser I can simply ssh webuser@localhost to switch user to webuser.

Note: I do not have sudo priveledges so I cannot sudo to switch to webuser from appuser.

Below is my playbook that is run with user appuser but needs to create a folder 04May2020 on localhost using webuser

- name: "Play 1"

  hosts: localhost
  remote_user: "webuser"
  vars:
    ansible_ssh_extra_args: -o StrictHostKeyChecking=no
    ansible_ssh_private_key_file: /app/misc_automation/ssh_keys_id_rsa

  tasks:
   - name: create folder for today's print
     file:
       path: "/webWeb/htdocs/print/04May2020"
       state: directory
     remote_user: webuser

However, the output shows that the folder is created with appuser instead of webuser. See output showing ssh connectivity with appuser instead of webuser.

ansible-playbook /app/Ansible/playbook/print_oracle/print.yml -i /app/Ansible/playbook/print_oracle/allhosts.hosts -vvv

TASK [create folder for today] ***********************************
task path: /app/Ansible/playbook/print_oracle/print.yml:33
Using module file /usr/lib/python2.7/site-packages/ansible/modules/files/file.py
Pipelining is enabled.
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: appuser
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 && sleep 0'

Can you please suggest if it is possible without sudo?


Solution

  • Putting all my comments together in a comprehensive answer.

    <127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: appuser

    This is indicating that you are connecting to localhost through the local connection plugin, either because you explicitelly re-declared the host as such or because you are using the implicit localhost. From discussions, you are in the second situation.

    When using the local connection plugin, as indicated in the above documentation, the remote_user is ignored. Trying to change the user has no effect as you can see in the below test run (user (u)ids changed):

    # Check we are locally running as user1
    $ id -a
    uid=xxxx(user1) gid=yyy(group1) groups=yyy(group1)
    # Running the same command through ansible returns the same result
    $ ansible localhost -a 'id -a'
    localhost | CHANGED | rc=0 >>
    uid=xxxx(user1) gid=yyy(group1) groups=yyy(group1)
    # Trying to change the remote user has no effect
    $ ansible localhost -u whatever -a 'id -a'
    localhost | CHANGED | rc=0 >>
    uid=xxxx(user1) gid=yyy(group1) groups=yyy(group1)
    

    Without changing your playbook and/or inventory, the only solution is to launch the playbook as the user who needs to create the directory.

    Since you have ssh available, an other solution is to declare a new host that you will use only for this purpose, which will target the local IP through ssh. (Note: you can explicitly declare localhost like this but then all connections will go through ssh which might not be what you want to do).

    Somewhere at the top of you inventory, add the line:

    localssh ansible_host=127.0.0.1
    

    And in your playbook, change

    hosts: localssh
    

    Now the connection to your local machine will go through ssh and the remote_user will be obeyed correctly.