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.
No comments yet.
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 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