regexreplaceansibletoml

Ansible lineinfile and replace modules, attempting to configure toml txt file


I have been trying to update configuration settings in a pi-hole.toml file.

After attempting lineinfile, it landed me on the replace module as the more appropriate to use. But I haven't had any luck with getting either to work.

Here's what I have so far in my replace module call. If the toml file is set to the default value of domain = "pi.hole"(leading whitespace intentional), it seems to think it's ok, and makes no changes. I would expect it to ensure the regexp match also matches the replace.;

- name: Configure pihole.toml settings.
  ansible.builtin.replace:
    path: /etc/pihole/pihole.toml
    regexp: "{{ item.regexp }}"
    replace: "{{ item.replace }}"
    after: "{{ item.after }}"
    before: "{{ item.before }}"
  loop:
    - { 
        regexp: '^  domain =.*$',
        replace: '  domain = "{{ pi_hole_domain }}" ### CHANGED, default = "pi.hole"',
        after: '^\[webserver\]$',
        before: '^  \[webserver.session\]'
      }

I have also tried this, having it specifically look for the default value of domain = "pi.hole", assuming if found, it would force a replace. But I get the same behavior. Ansible thinks it's ok, and makes no changes;

- name: Configure pihole.toml settings.
  ansible.builtin.replace:
    path: /etc/pihole/pihole.toml
    regexp: "{{ item.regexp }}"
    replace: "{{ item.replace }}"
    after: "{{ item.after }}"
    before: "{{ item.before }}"
  loop:
    - { 
        regexp: '^  domain = "pi\.hole".*$',
        replace: '  domain = "{{ pi_hole_domain }}" ### CHANGED, default = "pi.hole"',
        after: '^\[webserver\]$',
        before: '^  \[webserver.session\]'
      }

Here's the default pihole.toml file for reference: https://github.com/pi-hole/FTL/blob/master/test/pihole.toml, and the relevant part I want changed would be:

# Some other sections and configurations here

[webserver]
  # On which domain is the web interface served?
  #
  # Possible values are:
  #     <valid domain>
  domain = "pi.hole"

  # Some other configurations here

  [webserver.session]
 
  # Some other configurations here

I've been reading over other Questions/Answers, tried numerous other solutions, and checked with a couple AIs, but nothing I'm finding seems to line up with the behavior I'm seeing in my attempts. Thinking I'm overlooking something really simple, and just not seeing it :)


Solution

  • As pointed out in the manual of the replace module neither after nor before is using multiline. So ^ and $ does not represent the beginning or end of the line but of the whole file.

    Does not use MULTILINE, so ^ and $ will only match the beginning and end of the file.

    Reference: in both after and before parameters descriptions.


    So, here would be the task achieving what you are looking for:

    - name: Configure pihole.toml settings.
      ansible.builtin.replace:
        path: /etc/pihole/pihole.toml
        regexp: "{{ item.regexp }}"
        replace: "{{ item.replace }}"
        after: "{{ item.after }}"
        before: "{{ item.before }}"
      loop:
        - regexp: '^  domain =.*$'
          replace: '  domain = "{{ pi_hole_domain }}" ### CHANGED, default = "pi.hole"'
          after: '\[webserver\]'
          before: '  \[webserver.session]'