Ansible replace module duplicates replace values

357 views Asked by At

PROBLEM: Ansible 2.9 will duplicate entries in the "replace: " field of the replace module.

FILE TO CHANGE (/etc/netplan/50-cloud-init.yaml):

network:
ethernets:
    ens160:
        addresses:
        - 10.10.8.112/24
        gateway4: 10.10.8.1
        nameservers:
            addresses:
            - 10.10.8.15
version: 2

CODE:

- name: Check yaml has correct DNS values
  hosts: guest
  gather_facts: yes
  become: yes

  tasks:
          - name: Adjust yaml file
            replace:
              path: /etc/netplan/50-cloud-init.yaml
              after: '                addresses:'
              before: '    version: 2'
              regexp: '^(.+)$'
              replace: '                - 10.10.8.110\n                - 10.10.8.111\n                search:\n                - server.com\n            optional: true'

RESULTS:

  • If the original file only has one entry say "- 10.10.8.110", the sections will be replaced inbetween the "after" and "before". However if run again, expansible will duplicate the entries.

File contents will look like this after running the script again:

network:
ethernets:
    ens160:
        addresses:
        - 10.10.8.112/24
        gateway4: 10.10.8.1
        nameservers:
            addresses:
            - 10.10.8.110
            - 10.10.8.111
            search:
            - server.com
        optional: true
            - 10.10.8.110
            - 10.10.8.111
            search:
            - server.com
        optional: true
version: 2

Believe this has to do with idempotence, and can possibly be fixed with the regex. However I am not sure how to do this. All I want to do is to ALWAYS replace all values between after and before.

How can I accomplish this?

2

There are 2 answers

0
Zeitounator On

I would not count on before and after but build a regexp that matches exactly what I'm looking for and replace with back-references. Something like the following (not sexy but functional)


- name: Adjust yaml file
  replace:
    path: /etc/netplan/50-cloud-init.yaml
    regexp: >-
      (^\s*nameservers:\n\s*addresses:\n)[\S\s]*(version: 2)$
    replace: |-
      \g<1>           - 10.10.8.110
                  - 10.10.8.111
                  search:
                  - server.com
              optional: true\g<2>

Meanwhile, note that since your file is yaml, there are other ways to modify the data (combine objects, etc...) that might be simpler.

0
Alfonso On

The Code that you used was right, you just need to remove or before or after, if you use them at the same time the text will be inserted 2 times.

You need to do something like that (remove before):

    - name: Check yaml has correct DNS values
      hosts: guest
      gather_facts: yes
      become: yes

      tasks:

         - name: Adjust yaml file
           replace:
             path: /etc/netplan/50-cloud-init.yaml
             after: '                addresses:'
             regexp: '^(.+)$'
             replace: '                - 10.10.8.110\n                - 10.10.8.111\n                search:\n                - server.com\n            optional: true'