Avoid Ansible writing several times the same line in /etc/sudoers

Written by - 0 comments

Published on - Listed in Linux Ansible


When I ran an Ansible playbook which added an entry in /etc/sudoers for a user "developer" I came across something rather ugly: The line was written every time the playbook ran - resulting in an /etc/sudoers full of the same entries of the developer user.

The relevant task of the playbook looked like this:

  - name: DEVS - Add sudoers entry for developer
    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=(www-data)'
                insertafter='^# User privilege specification'
                line='developer ALL=(www-data) NOPASSWD: /bin/bash'
                state=present"

So what I want to achieve with this is the following:

In /etc/sudoers search for a line starting with "developer ALL=(www-data)".
If this line is not found, write the line "developer ALL=(www-data) NOPASSWD: /bin/bash" into /etc/sudoers, right after the line starting with "# User privilege specification".

To my big surprise, whenever I ran the playbook, it executed the task and set it to "changed". Meaning, the entry was added. So at the end /etc/sudoers contained several lines of "developer ALL=(www-data) NOPASSWD: /bin/bash". That's not what I wanted to achieve.

After some troubleshooting it turned out that the regular expression "developer ALL=(www-data)" didn't work because of the brackets ( ). As ansible is using python in the background, I checked out the python regular expression documentation and searched for an escape character. No big surprise here, the escape character is a backslash (\) as it is in Perl's regular expression, too.

I adapted the playbook to escape the brackets:

  - name: DEVS - Add sudoers entry for developer
    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=\(www-data\)'
                insertafter='^# User privilege specification'
                line='developer ALL=(www-data) NOPASSWD: /bin/bash'
                state=present"

But now I ran into a YAML syntax error:

ERROR! Syntax Error while loading YAML.

The error appears to have been in 'myplaybook.yaml': line 57, column 36, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=\(www-data\)'
                                   ^ here

So the escape character didn't work because YAML didn't like it. Finally I came across the answer: Wrap the character I want to escape in a separate character class and this is how it's done:

  - name: DEVS - Add sudoers entry for developer
    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=[(]www-data[)]'
                insertafter='^# User privilege specification'
                line='developer ALL=(www-data) NOPASSWD: /bin/bash'
                state=present"

The playbook now runs through and the sudoers entry only exists once.


Add a comment

Show form to leave a comment

Comments (newest first)

No comments yet.

RSS feed

Blog Tags:

  AWS   Android   Ansible   Apache   Apple   Atlassian   BSD   Backup   Bash   Bluecoat   CMS   Chef   Cloud   Coding   Consul   Containers   CouchDB   DB   DNS   Database   Databases   Docker   ELK   Elasticsearch   Filebeat   FreeBSD   Galera   Git   GlusterFS   Grafana   Graphics   HAProxy   HTML   Hacks   Hardware   Icinga   Influx   Internet   Java   KVM   Kibana   Kodi   Kubernetes   LVM   LXC   Linux   Logstash   Mac   Macintosh   Mail   MariaDB   Minio   MongoDB   Monitoring   Multimedia   MySQL   NFS   Nagios   Network   Nginx   OSSEC   OTRS   Office   OpenSearch   PGSQL   PHP   Perl   Personal   PostgreSQL   Postgres   PowerDNS   Proxmox   Proxy   Python   Rancher   Rant   Redis   Roundcube   SSL   Samba   Seafile   Security   Shell   SmartOS   Solaris   Surveillance   Systemd   TLS   Tomcat   Ubuntu   Unix   VMWare   VMware   Varnish   Virtualization   Windows   Wireless   Wordpress   Wyse   ZFS   Zoneminder