Restrict a user to only interact with a systemd service via Ansible

I want to have a user that is only able to start/stop/restart/status a service via an Ansible playbook.

The playbook looks like this:

host: my-server
remote_user: my-user
tasks:
  - name: "Start my-service"
    service:
      name: my-service
      state: started
      daemon_reload: yes
    become: true

I've tried using the sudoers file to restrict the privileges of my-admin but this does not works as the command Ansible is runnning is (simplified):

sudo /bin/sh -c "python /tmp/ansible-xxxxxx.py"

Obviously, I can't allow my-admin to run /bin/sh as root as this would allow everything to be run as root. What configuration should I ? What should I change ?


Solution 1:

In general:

You can't. Ansible privilege escalation is all or nothing. See: https://docs.ansible.com/ansible/latest/user_guide/become.html#privilege-escalation-must-be-general

Limit with sudo

The classic approach: Your user is allowed to access that system and you create a sudo policy that severely restricts and limits what commands (and with which arguments) your user can run with sudo. That is possible, quite easy to maintain but comes with the sudo limitation that then those commands need to be used in the exact syntax of your policy.
That more or less prohibits using native Ansible modules and privilege escalation methods to perform the tasks.

You can still use a playbook, but then you will get something ugly like:

tasks:
  - name: "Start my-service with sudo"
    ansible.builtin.command: /usr/bin/sudo /usr/bin/systemctl start my-service.service

and even uglier kludges when your sudo policy still requires a password as well.

Use Ansible tower:

To avoid giving your user both access that system and setting up that restricted sudo policy:

  • You set up a service account for Ansible playbooks that has the required unlimited privilege escalation.
  • You set up Ansible Tower as the only system with the credentials to log in with the Ansible service account.
  • You use the user management and ACL's from Ansible Tower to designate which plays your user can run against which hosts. Your users plays will be executed using the Ansible service account, but you don't need to hand those over to your user.

https://docs.ansible.com/ansible-tower/latest/html/userguide/security.html