Using the replace in Ansible

Viewed 178

I have this code trying to replace string.

File:

<?php
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'some-server.domain.com';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'postfixadmin';
$CONF['database_name'] = 'postfix';
$CONF['encrypt'] = 'dovecot:SHA512';
$CONF['configured'] = true;
?>

Tasks:

- name: Replace by setting db parms for PostFixAdmin Host
  replace:
    path: /etc/postfixadmin/config.local.php
    regexp: "$CONF['database_host'] = 'some-server.domain.com';"
    replace: "$CONF['database_host'] = '{{db_host}}';"
    backup: yes
  
- name: Replace by setting db parms for PostFixAdmin User
  replace:
    path: /etc/postfixadmin/config.local.php
    regexp: "$CONF['database_user'] = 'postfix';"
    replace: "$CONF['database_user'] = '{{db_user}}';"
    backup: yes

I have tried \ the $ and ..

Also

- name: Replace by setting db parms for PostFixAdmin Host
  lineinfile:
    path: /etc/postfixadmin/config.local.php
    regexp: ^\\$CONFIG\\['database_host'\\] = .*$
    line: "$CONF['database_host'] = '{{db_host}}';"

does not replace it add a second outside of php like this (at the end of the file):

?>
$CONF['database_host'] = 'localhost';

How can I do this?

1 Answers

Because it is a regex, you have to escape all the characters that do have a meaning in a regex and this is the case for

  • the dollar sign $ that means end of the string
  • the opening and closing square brackets [] that are delimiting characters class.
  • the dot . that match any single character

Your replace tasks should, then, be:

- name: Replace by setting db parms for PostFixAdmin Host
  replace:
    path: /etc/postfixadmin/config.local.php
    regexp: "\\$CONF\\['database_host'\\] = 'some-server\\.domain\\.com';"
    replace: "$CONF['database_host'] = '{{db_host}}';"
    backup: yes

- name: Replace by setting db parms for PostFixAdmin User
  replace:
    path: /etc/postfixadmin/config.local.php
    regexp: "\\$CONF\\['database_user'\\] = 'postfix';"
    replace: "$CONF['database_user'] = '{{db_user}}';"
    backup: yes

The regex ^\\$CONF\\['database_host'\\] = .*$, is also correct, but you have two issues in your trial:

  1. the regex as you show it match the array $CONFIG, when your array is named $CONF
  2. that regex should be quoted:
    regexp: "^\\$CONF\\['database_host'\\] = .*$"
    

Last but not least, a small explanation of the behaviour of lineinfile; from the documentation:

If specified regular expression has no matches, EOF will be used instead.

Source: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html#parameter-insertafter

So, that means that the new line is added at the end of the file because your regex do not match anything as it is currently written.

Related