Editing /etc/sudoers with ansible + sed = gobs back slashes?

I am setting up a bunch of Fedora 17 nodes. Right after the server provisioning, I use ansible to do configuration management.

I wanted to add a Cmd_Alias to the /etc/sudoers and decided to use a playbook to get it done.

Here is the result (line numbers included):

    47 ## Drivers
    48 # Cmnd_Alias DRIVERS = /sbin/modprobe
    49
    50 ## System on/off
    51 Cmnd_Alias SHUTDOWN = /sbin/halt, /sbin/shutdown,\
    52 /sbin/poweroff, /sbin/reboot, /sbin/init
    53
    54 # Defaults specification
    55

and below is the sed statement that I used in the playbook:

[...]
    - name: Add an alias to the /etc/sudoer file. Make a backup copy too
      action: command /bin/sed -iorig '50 i\#\# System on/off\\\nCmnd_Alias SHUTDOWN = /sbin/halt, /sbin/shutdown,\\\\\\\n/sbin/poweroff, /sbin/reboot, /sbin/init\\\n' /etc/sudoers
[...]

It took me a while to get the number of back slashes right and got the result shown above (note that I used GNU sed's GNU extensions in the above statement). But I don't understand why so many back slashes are needed and would appreciate some enlightening. Furthermore, if anyone knows of a more clean way to do the task, I would appreciate a hint or suggestion.

Regards,

--Zack

First, it might be easier to just use a template.

The need for so many slashes has to do with how many times you interpolate (in shell, ssh, shell and sed itself), it gets tricky when each level can interpret variable substitution and escapes.

As Brian said, you want to use a template.

The main reason for this is you want to know EXACTLY what your
sudoer's policy is, and line editing is a really good way to have
absolutely no clue what your configuration is on the remote end.

Templates are authorative and are your friend.

You should also avoid non-idempotent uses of the "command" module,
whenever possible, this is any case where you use command without the
'creates=' flag.... though this is not always avoidable, it makes
for a much more reliable playbook when you do this.

(Anyway, your backspace issue is all because of sed, nothing ansible specific.)

--Michael

Hi Brian and Michael,

Thanks for your enlightening. I will revise my playbook ASAP.

Best Regards,

--Zack

As Brian said, you want to use a
template.

The main reason for this is you want to know EXACTLY what
your sudoer's policy is, and line editing is a really good way to
have absolutely no clue what your configuration is on the remote
end.

Templates are authorative and are your friend.

You should also avoid non-idempotent uses of the "command"
module, whenever possible, this is any case where you use command
without the 'creates=' flag.... though this is not always
avoidable, it makes for a much more reliable playbook when
you do this.

(Anyway, your backspace issue is all because of sed, nothing
ansible specific.)

--Michael

[...]

Depends what you’re trying achieve with the DRIVERS alias, but I’d probably redo this as following:

  • At build time add #includedir /etc/sudoers.d to the very end of sudoers, and create /etc/sudoers.d. Ansible could be used to do that after build time, of course.
  • Add your modifications using new files under /etc/sudoers.d - e.g. 01drivers containing DRIVERS alias and things that use it.

This might not be applicable for your use cases but I thought it’s worth outlining in case you hadn’t come across include and includedir

Will

Hi Will,


Excellent suggestion too. Looks like I must do another round of playbook update :wink:


BTW, I wasn’t going to touch the Drivers alias, I was trying to add an alias that list commands that admin users (other than the real root) are not allowed to run.


Best,


– Zack



> Depends what you’re trying achieve with the DRIVERS alias, but I’d probably redo this as following:
>
> * At build time add #includedir /etc/sudoers.d to the very end of sudoers, and create /etc/sudoers.d. Ansible could be used to do that after build time, of course.
> * Add your modifications using new files under /etc/sudoers.d - e.g. 01drivers containing DRIVERS alias and things that use it.
>
> This might not be applicable for your use cases but I thought it’s worth outlining in case you hadn’t come across include and includedir
>
> Will
> […]


|

Ah, quite right, my mistake regarding drivers rather than shutdown - seems like it should still help though :slight_smile:

Will