Search code examples
ansiblesystemd

Ansible systemctl --user for another user


I'm logging into another computer as the unprivileged user ansible and I'd like to have ansible enable a systemd user service for the user bob.

Without ansible, the solution would be ssh bob@machine followed by systemctl --user enable service

However, with ansible, there are two problems:

  1. Newer versions of ansible will refuse to become the unprivileged user bob if already logged in as another unprivileged user (ansible).
  2. Even if this worked, dbus would not be started and systemctl would not be able to talk to systemd (if I understood this correctly).

A horribly ugly workaround would be to execute the shell command, have the remote host ssh into itself as bob and run the systemctl raw command there.

Is there a nicer way to get this done?


Solution

  • Both options are feasible.

    1. remote_user: bob
    - hosts: test_01
      become: no
      remote_user: admin
    
      tasks:
    
        - command: whoami
          register: result
        - debug:
            var: result.stdout
    
        - command: whoami
          remote_user: bob
          register: result
        - debug:
            var: result.stdout
    

    gives (abridged)

      result.stdout: admin
      result.stdout: bob
    
    1. pipelining = true quoting from Becoming an Unprivileged User

    Use pipelining. When pipelining is enabled, Ansible doesn’t save the module to a temporary file on the client. Instead, it pipes the module to the remote python interpreter’s stdin. Pipelining does not work for python modules involving file transfer (for example: copy, fetch, template), or for non-python modules.

    - hosts: test_01
      become: no
      remote_user: admin
    
      tasks:
    
        - command: whoami
          register: result
        - debug:
            var: result.stdout
    
        - command: whoami
          become_user: bob
          become_method: sudo
          become: yes
          register: result
        - debug:
            var: result.stdout
    

    gives (abridged) the same result

      result.stdout: admin
      result.stdout: bob
    

    with

    shell> grep pipe ansible.cfg 
    pipelining = true