Ansible replace regex with variable

ansible

I am trying to replace localhost in the string

$amp_conf['AMPDBHOST'] = 'localhost';

with the content of the variable {{ asterisk_db_host }}, which is 172.17.0.3.

Even though

- replace:
    dest: /usr/src/freepbx/installlib/installcommand.class.php
    regexp: '(\$amp_conf\[.AMPDBHOST.\] = .)localhost(.;)'
    replace: '\1\2'

perfectly results in

$amp_conf['AMPDBHOST'] = 'localhost';

- replace:
    dest: /usr/src/freepbx/installlib/installcommand.class.php
    regexp: '(\$amp_conf\[.AMPDBHOST.\] = .)localhost(.;)'
    replace: '\1{{ asterisk_db_host }}\2'

as well as

- replace:
    dest: /usr/src/freepbx/installlib/installcommand.class.php
    regexp: '(\$amp_conf\[.AMPDBHOST.\] = .)localhost(.;)'
    replace: '\1{{ asterisk_db_host|regex_escape() }}\2'

replace the string with O2.17.0.2'; or O2\.17\.0\.2';.

What am I doing wrong here? How can I properly do this replacement?

Best Answer

Your replacement string looks like this:

'\1{{ asterisk_db_host }}\2'

After Jinja templating, this is what actually gets used as the replacement string in the regex module:

'\1172.17.0.3\2'

Look at that first term. It's no longer \1, it's now \1172, which is clearly erroneous. One way of solving this is to make the quotes around the value part of your replacement (because when you do this, there will be a non-digit character -- the quote -- separating your backreference from the value of the template expansion). Here's one option:

- hosts: localhost
  gather_facts: false
  vars:
    asterisk_db_host: "172.17.0.3"
  tasks:
    - replace:
        dest: ./cfgfile
        regexp: >-
          (\$amp_conf\[.AMPDBHOST.\] = )'localhost'(;)
        replace: >-
          \1'{{ asterisk_db_host }}'\2

This uses YAML block quoting (>-) so that we don't need to worry about escaping quotes in our expressions, and it seems to do the right thing in my simple tests.