5

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.

asked Apr 18, 2017 at 2:26
6
  • And what do you want to achieve with this? The results seem perfectly fine. The string is not in the input file, so it doesn't get replaced. The task ends with ok status. Commented Apr 18, 2017 at 2:31
  • And for this particular example why aren't you using lineinfile module? Commented Apr 18, 2017 at 2:45
  • @techraf: I had tried using the lineinfile module with same results. thus tried the replace module. Commented Apr 18, 2017 at 2:51
  • @techraf, can you enlighten me as to what is wrong with the regexp that it does not find the string? Please reference the third line in the snip: "${distro_id}:${distro_codename}-system"; Commented Apr 18, 2017 at 2:52
  • You don't have security string in your input file. And regex engine won't match security with system. Do you feel enlightened now? Commented Apr 18, 2017 at 2:53

1 Answer 1

7

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";'
answered Apr 18, 2017 at 3:34
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for helping me understand the multiple issues.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.