Search code examples
bashansiblesudopulseaudio

Ansible: Run command as different user but not with sudo


My overall aim is to restart pulseaudio for a specific user via ansible (so if you have a better idea how to do this, I am open to hear it :) )

I want to run the following command as the user myuser, and according to pulseaudio this should not be done as sudo/root.

$([[ $(pulseaudio -k) -eq 0 ]] || exit 0; sleep 5; [[ $(pulseaudio -D --exit-idle-time=-1) -eq 0 ]] || exit 0)

that works nice if I test it one the machine it self. It kills pulseaudio if it's running and than starts it again and it does not fail, if pulseaudio was already stopped.

Attempt 1 [Waiting til timeout for password]:

My ansible task (as part of a role) looks like this:

- name: restart pulse audio
  shell: '$([[ $(pulseaudio -k) -eq 0 ]] || exit 0; sleep 5; [[ $(pulseaudio -D --exit-idle-time=-1) -eq 0 ]] || exit 0)'
  args:
    executable: /bin/bash
  become: true
  become_method: sudo
  become_flags: "su - {{ ansible_user }} -c"

But if I run that I get the error FAILED! => {"msg": "Timeout (12s) waiting for privilege escalation prompt: "}

If I login to that machine as root and enter sudo su - myuser I get a prompt as myuser how I would expect it.

So how can I specify a password for myuser so ansible can use it?

Attempt 2 [Incorrect su password]:

ansible task:

- name: restart pulse audio
  shell: '$([[ $(pulseaudio -k) -eq 0 ]] || exit 0; sleep 5; [[ $(pulseaudio -D --exit-idle-time=-1) -eq 0 ]] || exit 0)'
  args:
    executable: /bin/bash
  become: true
  become_method: su
  become_user: myuser

I also tried to use become_user instead of the become_flags but with no success. Then I got the error: FAILED! => {"msg": "Incorrect su password"}

Attempt 3 [Command get's executed as sudo]:

If I tried Calum Halpin first suggestion, pulseaudio gets startet but as sudo, what is not what I want, I need pulseaudio to be startet by myuser.

ansible task:

- name: restart pulse audio
  shell: '$([[ $(pulseaudio -k) -eq 0 ]] || exit 0; sleep 5; [[ $(pulseaudio -D --exit-idle-time=-1) -eq 0 ]] || exit 0)'
  args:
    executable: /bin/bash
  become: true
  become_method: sudo
  become_user: myuser

I get the following output:

{"changed": true, 
"cmd": "$([[ $(pulseaudio -k) -eq 0 ]] || exit 0; sleep 5; [[ $(pulseaudio -D --exit-idle-time=-1) -eq 0 ]] || exit 0)", 
"delta": "0:00:05.110839", "end": "2019-06-23 11:11:43.686776", "rc": 0, "start": "2019-06-23 11:11:38.575937", 
"stderr": "E: [pulseaudio] main.c: Failed to kill daemon: No such file or directory\nW: [pulseaudio] main.c: This program is not intended to be run as root (unless --system is specified).", 
"stderr_lines": ["E: [pulseaudio] main.c: Failed to kill daemon: No such file or directory", "W: [pulseaudio] main.c: This program is not intended to be run as root (unless --system is specified)."], 
"stdout": "", "stdout_lines": []}

Attempt 2.1 & 3.1 [using remote_user: myuser]

I tried setting the remote_user to myuser in the palybook, but all results kept the same.

My configuration / environment:

My become variables are configured like this:

ansible_connection: ssh
ansible_user: myuser
ansible_ssh_pass: 1234
ansible_become: yes
ansible_become_user: root
ansible_become_pass: 1234

The playbook looks like:

- hosts: myhost
  connection: local
  become: ansible_become
  become_user: ansible_become_user

  roles:
    - role: pulse-audio-config

Solution

  • Solution:

    After several different approaches I got it working with the following configuration:

    The variables in the inventory:

    ansible_connection: ssh
    ansible_user: myuser
    ansible_ssh_pass: 1234
    ansible_become: yes
    ansible_become_user: root
    ansible_become_pass: 1234
    

    in the playbook:

    - hosts: myhost
      connection: local
    
      roles:
        - role: another-role
        - { role: pulse-audio-config,
          ansible_become_user: nas }
        - role: another-other-role
    

    in the role:

    - name: restart pulse audio
      shell: '$([[ $(pulseaudio -k) -eq 0 ]] || exit 0; sleep 5; [[ $(pulseaudio -D --exit-idle-time=-1) -eq 0 ]] || exit 0)'
      args:
        executable: /bin/bash
      become: true
      become_method: sudo
      become_flags: "su - {{ ansible_become_user }} -c"