I am having trouble getting a regex pattern to match in Ansible 2. Could someone help me understand what I am doing wrong? Thank you.
--- # Disable auto update for Ubuntu
- hosts: nonedgeLinux
become: yes
tasks:
- name: disable auto updates
replace:
dest: /etc/apt/apt.conf.d/50unattended-upgrades
regexp: '(?:[ \t]*\"\${distro_id}:\${distro_codename}-security\";)'
replace: '// "\${distro_id}:\${distro_codename}-security\";'
I used https://regex101.com/ to validate the regex against a copy/paste of the file contents being searched. This test reports the regexp pattern is correct. Each time it is run on a Ubuntu 16.04.2 box I get the following results:
root@sbx54:/data/scripts/ansible# ansible-playbook disableAutoUpdate.yml -vvvv
Using /data/scripts/ansible/ansible.cfg as config file
Loaded callback default of type stdout, v2.0
1 plays in disableAutoUpdate.yml
PLAY ****************************************************************************
TASK [setup] *******************************************************************
ESTABLISH LOCAL CONNECTION FOR USER: root
localhost EXEC ( umask 22 && mkdir -p "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168 )" )
localhost PUT /tmp/tmpkYPc6g TO /root/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168/setup
localhost EXEC LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168/setup; rm -rf "/root/.ansible/tmp/ansible-tmp-1492480514.73-9504514182168/" > /dev/null 2>&1
ok: [localhost]
TASK [disable auto updates] ****************************************************
task path: /data/scripts/ansible/disableAutoUpdate.yml:15
ESTABLISH LOCAL CONNECTION FOR USER: root
localhost EXEC ( umask 22 && mkdir -p "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124 )" )
localhost PUT /tmp/tmpG3gchf TO /root/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124/replace
localhost EXEC LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124/replace; rm -rf "/root/.ansible/tmp/ansible-tmp-1492480515.71-278594852314124/" > /dev/null 2>&1
ok: [localhost] => {"changed": false, "invocation": {"module_args": {"backup": false, "content": null, "delimiter": null, "dest": "/etc/apt/apt.conf.d/50unattended-upgrades", "directory_mode": null, "follow": false, "force": null, "group": null, "mode": null, "owner": null, "regexp": "(?:(?!\\/\\/).*[ \\t]*\\\"\\${distro_id}:\\${distro_codename}-security\\\";)/g", "remote_src": null, "replace": "replaced", "selevel": null, "serole": null, "setype": null, "seuser": null, "src": null, "validate": null}, "module_name": "replace"}, "msg": ""}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
Here is a snip of the file being searched:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-system";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
# ansible --version
ansible 2.0.0.2
config file = /data/scripts/ansible/ansible.cfg
configured module search path = Default w/o overrides
One last note: I did have success in search and replace within this file when only looking for strings. When looking for the entire line is when this fails. Additionally I have tried escaping the special characters as well, e.g. [/][/] in place of \/\/\, etc. with no luck.
1 Answer 1
On top of the mistake in trying to match security with system, you don't need to escape the double quotes in either of the arguments or the dollar sign in the replace argument (otherwise the backslash will be inserted into the file):
- name: disable auto updates
replace:
dest: /etc/apt/apt.conf.d/50unattended-upgrades
regexp: '(?:[ \t]*"\${distro_id}:\${distro_codename}-system";)'
replace: '// "${distro_id}:${distro_codename}-system";'
And you can achieve the same result using lineinfile module (which makes code a bit more readable, imho):
- name: disable auto updates
lineinfile:
dest: /etc/apt/apt.conf.d/50unattended-upgrades
regexp: '"\${distro_id}:\${distro_codename}-system"'
line: '// "${distro_id}:${distro_codename}-system";'
okstatus.lineinfilemodule?securitystring in your input file. And regex engine won't matchsecuritywithsystem. Do you feel enlightened now?