Ansible: best practice for maintaining list of sudoers
Solution 1
That line isn't actually adding an users to sudoers, merely making sure that the wheel
group can have passwordless sudo for all command.
As for adding users to /etc/sudoers
this is best done by adding users to necessary groups and then giving these groups the relevant access to sudo. This holds true when you aren't using Ansible too.
The user module allows you to specify an exclusive list of group or to simply append the specified groups to the current ones that the user already has. This is naturally idempotent as a user cannot be defined to be in a group multiple times.
An example play might look something like this:
- hosts: all
vars:
sudoers:
- user1
- user2
- user3
tasks:
- name: Make sure we have a 'wheel' group
group:
name: wheel
state: present
- name: Allow 'wheel' group to have passwordless sudo
lineinfile:
dest: /etc/sudoers
state: present
regexp: '^%wheel'
line: '%wheel ALL=(ALL) NOPASSWD: ALL'
validate: visudo -cf %s
- name: Add sudoers users to wheel group
user:
name: "{{ item }}"
groups: wheel
append: yes
with_items: "{{ sudoers }}"
Solution 2
I prefer to use /etc/sudoers.d/
for this if possible (this is less risky, more modular and self-decriptive), so this approach looks like:
$ cat files/*
%admins ALL=(ALL) NOPASSWD: ALL
$ cat tasks/*
- name: sudoers | Create sudoers.d files
copy:
src: ./
dest: /etc/sudoers.d
owner: root
group: root
mode: ug+rwX,o=
force: yes
File are pre-checked with visudo -cf file_name
.
Comments
-
chishaku almost 4 years
In the documentation, there is an example of using the
lineinfile
module to edit/etc/sudoers
.- lineinfile: "dest=/etc/sudoers state=present regexp='^%wheel' line='%wheel ALL=(ALL) NOPASSWD: ALL'"
Feels a bit hackish.
I assumed there would be something in the
user
module to handle this but there doesn't appear to be any options.What are the best practices for adding and removing users to
/etc/sudoers
? -
xenithorb over 7 years
validate: visudo -cf %s
as an attribute of thelineinfile
task will ensure that you don't mess something up, by running it through the validation command first. -
Matt Hughes almost 6 yearsNote that the
validate
command will probably need the full path tovisudo
to work. -
Todd Walton over 4 yearsThe problem with this approach is that you have to a) be sure you have the wheel group already there and already enabled in sudoers, and b) be sure that you want to put the user into the wheel group and not some other one. What if you want a user to be NOPASSWD, but limit their commands? The lineinfile module gets trickier when you need to insert a line but not at the end. (Because inserting it at the end would break the #includedir statement, which must be on the last line.)
-
AdamKalisz about 4 yearsBtw. if you are wondering, what the
%s
invalidate
means, it is the destination (dest) or path of the file that is supposed to be modified. Here is the documentation. -
maxschlepzig over 3 yearsYou are missing the filename in
src:
. Also,force: yes
is superfluous as this is the default. Perhaps it makes sense to be more explicit about the destination as this would create/etc/sudoers.d
as a file if it doesn't exist ... -
dess over 3 yearsThank you for the note! Actually, I'm considering following: file name isn't missed, syntax means all contents of directory;
force
is used for module action specifics emphasis, could be omitted; ifdest:
is a non-existent path andsrc:
is a directory (which is)dest:
path (directory, not file) is created. -
maxschlepzig over 3 yearsOk,
./
looked like an oversight. Having a subdirectory in your files directory - such that you could use - say -src: sudoers.d
- arguably would make this pattern more obvious. -
JeremyCanfield almost 3 yearsGreat answer. A slightly different approach would be to use the
copy
module instead of thelineinfile
module to copy the sudoers files from the control node to each managed node. There are pros and cons to using the copy vs. lineinfile module. I tend to like the copy module to have a single, standardized file on the control node to ensure each managed node is using the same exact file. But, of course, there are possible drawbacks to using copy. Just food for thought here. -
Darren Felton about 2 yearsPersonally I prefer
ansible.builtin.template
overansiblt.builtin.copy
oransible.builtin.file
. While we maybe don't need variables inside the file, this allows us to report accurately at the end of the playbook if something has changed or not.