regexansibletelegraf-inputs-plugin

How to Insert a new string into telegraf.conf's inputs.ping using ansible regexp


I'm trying to use ansible to update telegraf.conf's [[inputs.ping]].

telegraf.conf looks like the following:

[[inputs.ping]]
  urls = ["tac-temp1","tac-temp2", "tac-temp3","tac-temp4"] #tac
  count = 30
  timeout = 15.0
  [inputs.ping.tags]
  name = "tac"

[[inputs.ping]]
  urls = ["prod-temp1","prod-temp2", "prod-temp3","prod-temp4"] #prod
  count = 30
  timeout = 15.0
  [inputs.ping.tags]
  name = "prod"

[[inputs.ping]]
  urls = ["test-temp1","test-temp2", "test-temp3","test-temp4"] #test
  count = 30
  timeout = 15.0
  [inputs.ping.tags]
  name = "test"

I'm trying to add ,"tac-temp10" after ,"tac-temp4" in line 2 shown above.

- hosts: Servers
  become: yes
  become_method: sudo
  tasks:
    - name: Loading telegraf.conf content for search
      shell: cat /tmp/telegraf.conf
      register: tele_lookup

    - name: Adding Server to  /tmp/telegraf.conf if does not exists
      lineinfile:
             path: /tmp/telegraf.conf
             state: present
             regexp: '^((.*)"] #tac$)'       
             line: ',"tac-temp10"'      
             backup: yes
      when: tele_lookup.stdout.find('tac-temp10') != '0'

regexp: '^((.*)"] #tac$)' is replacing the whole line with ,"tac-temp10". Expected output:

[[inputs.ping]]
  urls = ["tac-temp1","tac-temp2", "tac-temp3","tac-temp4","tac-temp10"] #tac
  count = 30
  timeout = 15.0
  [inputs.ping.tags]
  name = "tac"

Solution

  • Warning: Ugly regexp ahead. Beware of unpredictable understanding for next guys (including you after time passed by...) doing maintenance.

    The following will add your server at the end of the list if it is not already present (anywhere in the list) with a single idempotent task.

        - name: add our server if needed
          lineinfile:
            path: /tmp/test.conf
            backup: yes
            state: present
            regexp: '^( *urls *= *\[)(("(?!tac-temp10)([a-zA-Z0-9_-]*)",? *)*)(\] #tac)$'
            backrefs: yes
            line: '\1\2, "tac-temp10"\5'
    

    You need to use backreferences to put back on the line the already matched parts of the expression. I used backup: yes so I could easily come back to the original for my tests. Feel free to drop it.

    As you can see (and as advised in my warning) this is pretty much impossible to understand for anyone having to quickly read the code. If you have to do anything more fancy/complicated, consider using a template and storing your server list in a variable somewhere.