How do I write an Ansible task to run a PHP script as a third user; not the root user and not the connecting user, but the “webserver” user?
The NextCloud administration program occ
, according to the documentation, must be run as the webserver user:
sudo -u www-data php occ
To become a different user for running a command, Ansible provides the become
feature. The Ansible documentation sternly recommends against attempting to run commands as a different, non-root user:
Everything is fine if the module file is executed without using become
, when the become_user
is root, or when the connection to the remote machine is made as root. In these cases Ansible creates the module file with permissions that only allow reading by the user and root, or only allow reading by the unprivileged user being switched to.
However, when both the connection user and the become_user
are unprivileged, the module file is written as the user that Ansible connects as (the remote_user
), but the file needs to be readable by the user Ansible is set to become.
Using become_user
to that user
The connection user has sudo
permission to run commands as the third user:
$ sudo -u www-data whoami
www-data
When I use become_user
on the task, to run the command as that user:
- name: "NextCloud: Instance configuration"
become_user: "{{ web_process_user }}"
command:
cmd: >-
php "{{ apache_nextcloud_dir }}/occ" maintenance:install
--no-interaction
…
UPDATE: um, it works. I don't know what changed, but in trying to reproduce the problem, it stopped.
Using shell
with an explicit sudo
invocation as that user
When I configure the Ansible task with a shell
command:
shell: >-
su '{{ web_process_user }}' --shell '/bin/bash' -c ' \
php "{{ apache_nextcloud_dir }}/occ" …
Ansible complains:
[WARNING]: Consider using 'become', 'become_method', and 'become_user' rather than running su
I'd love to do that. Ansible's become
would be a much more graceful way than this shell: su
hack.
But when using become
, the problems described in the Ansible documentation occur: the task module sent across the connection for running that command, fails to get the privilege to create its temporary files.
The Ansible documentation advises to either:
- “use pipelining”: That loses the advantages of the default task-module system.
- “avoid becoming an unprivileged user”: Not an option, because the
unprivileged webserver user is required for running this command
correctly.
How should I make an Ansible task that runs php "{{ apache_nextcloud_dir }}/occ"
as the unprivileged, third user {{ web_process_user }}
?
UPDATE: the become
functionality appears to work correctly now.