naftuli.wtf An urban mystic, pining for conifers in a jungle of concrete and steel.

Managing sudoers in Ansible

Ansible is awesome. You can automate all the things, which is a motto to live by.

Automate ALL THE THINGS

Let’s automate sudoers permissions. This operation is one of the more dangerous operations you can run in automation, right after dd or parted, with a little less risk. If sudoers gets screwed up, you won’t be able to gain root, and that’s a perfect way to ruin an otherwise good day.

Luckily, there is a sudoers validation tool called visudo as you probably know, and it happens to allow automated validation like so:

visudo -q -c -f filename

Ansible’s template module allows us to call a script to validate our output file before moving it into place. This makes managing sudoers pretty much bulletproof, as long as you don’t push valid-yet-incorrect configuration.

As is pretty standard in cloud deployments these days, we’re going to allow all users in group adm to have passwordless sudo rights. We’re also going to preserve the SSH_AUTH_SOCK environment variable in sudo, which can cause problems. Here’s our sudoers file we’ll be installing:

# Preserve SSH_AUTH_SOCK env variable
Defaults env_keep+=SSH_AUTH_SOCK
# Allow users in group adm to gain sudo without password
%adm   ALL=(ALL:ALL) NOPASSWD: ALL

Now, here’s where how we’ll deploy it in Ansible, validating it for syntax:

- hosts: all
  tasks:
    - name: add admin sudoers
      template:
        src: conf/sudoers.d/adm
        dest: /etc/sudoers.d/adm
        mode: '0440'
        owner: root
        group: root
        validate: 'visudo -q -c -f %s'

This will generate a file from a local Jinja 2 template on the destination host, then run the validation step, and then finally move it into place. If it doesn’t pass validation, nothing happens. The Ansible step will fail, and you won’t be locked out. Ansible saves the day again!