Authorize nginx reload without providing become-pass and full sudo privileges

Hi,

I am migrating to a new architecture and I have provisioned my servers with an ansible playbook. I am also using ansible to deploy my source code.

I want to be able to reload nginx when the configuration change without having to :

  • give sudo rights on ALL commands to the deploy user
  • having to pass a become-pass in the command line

In my previous installation, I was doing everything manually and I had added this settings to allow my deployment user to reload the nginx configuration :

deploy ALL(ALL) NOPASSWD: /usr/local/sbin/nginx -t, /usr/local/sbin/nginx -s reload

How can I have the same feature with Ansible ? Or what is the command which is executed when we use the service module and the state reloaded ?

Right now, I have this error :

sshpass -d15 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=deploy -o ConnectTimeout=10 -o ControlPath=/home/deploy/.ansible/cp/ansible-ssh-%h-%p-%r -tt x.x.x.x ‘/bin/bash -c ‘"’“'sudo -H -S -n -u root /bin/bash -c '”’“'”‘"’“'”‘"’“‘echo BECOME-SUCCESS-lttadeaqujrmkjjfqaswosxpazzwmsoj; /usr/bin/python /home/deploy/.ansible/tmp/ansible-tmp-1485445894.86-256748839860893/systemd.py; rm -rf “/home/deploy/.ansible/tmp/ansible-tmp-1485445894.86-256748839860893/” > /dev/null 2>&1’”‘"’“'”‘"’“'”‘"’ && sleep 0’“'”‘’

fatal: [x.x.x.x]: FAILED! => {
“changed”: false,
“failed”: true,
“invocation”: {
“module_args”: {
“name”: “nginx”,
“state”: “reloaded”
},
“module_name”: “service”
},
“module_stderr”: “Shared connection to x.x.x.x closed.\r\n”,
“module_stdout”: “sudo: a password is required\r\n”,
“msg”: “MODULE FAILURE”
}

Note that I am provisioning a CentOS 7.3 server with Ansible 2.2.1.

Thanks

As you can see in the command that is executed by Ansible:

sudo -H -S -n -u root /bin/bash

You cannot restrict individual commands, as we execute everything through a sudoed shell.

The recommendation is that sudo should be configure to allow any command to be executed, and not be restricted.

The only other option would be to not use the purpose built Ansible modules, but instead use raw or such to execute those commands directly.

You can use ansible-vault to encrypt the host_vars file that contains
the become password, and either enter the vault password on execution
or have ansible read it from some file.

But that might not achieve what you want to do. So, what is your goal?
Do you want to restrict the one calling ansible to only be able to
reload nginx?
Then, as Matt said, using the raw module with an explicit sudo call,
that is allowed in /etc/sudoers might work (but is kind of ugly, of
course).

Johannes

Yes my goal was to restrict on the OS side the commands the deployment user is allowed to execute.

I did not know the raw module. i am looking into it. It does not seem “ugly” :wink:

I think that it is quite a drawback on Ansible. If you use it for code shipping, you will have to do some tasks which needs privileges escalation (reload nginx or something else). And the people who are doing the delivery are not necessary engineers who should have access to all commands with a simple sudo. But if this raw module allows me to do this, so big up Ansible !!! :wink:

Anyway thanks for pointing that module to me.

Thanks, I am looking at the raw module which seems to suite my need. And what about the shell module with a previously delivered shell script containing my reload nginx command ? Would it work ?

If you do not need to do anything else via ansible (at least the
people you mention) then raw module or shell with a script might be best.

As a side not, using a git repository with a post-receive hook that
might be an option for people more used to git than to sudo...
Depends on your exact environment, so YMMV.

Johannes