2

In ansible, I'd like to replace this:

  <sadmin>
    <user>admin@localhost</user>
  </sadmin>

with this:

<sadmin>
   <user>user1@somedomain</user>
   <user>user2@somedomain</user>
   <user>user3@somedomain</user>
 </sadmin>

I've tried using the replace module, but don't know if the regex can span multiple lines (how would I use python raw notation for newlines?). I tried the xml module but I don't think this is actually an XML file since it kept adding a <?xml version='1.0' encoding='UTF-8'?> header to the top of the file. How can I do this? Better to use a template?

  - name: add replacements to jabber config files
    replace:
      path   : "/etc/jabberd2/{{ item.path }}"
      regexp : "{{ item.regex }}"
      replace: "{{ item.replace }}"
    with_items:
      - { path: 'muc.xml', regex: 'conference.localhost', replace: 'conference.mydomain' }
      - { path: 'muc.xml', regex: '<sadmin>.*</sadmin>',      replace: '<sadmin><user>user1@somedomain</user>\n<user>user2@somedomain</user></sadmin>' }
  • I believe that using the xml module shoudl give you the cleanest results. Did you check if the xml header does any harm to jabber? If not I would recommed to go with the xml module. Otherwise you might want to check if the blockinfile module could be used here. – Henrik Pingel May 9 '19 at 8:56
  • Is there a good reason that you can't generate this file from scratch and use the template mechanism instead? – chicks May 9 '19 at 13:55
  • The templates work well but then everytime a new version of the software comes along I have to vimdiff my templates. It seems less hassle to just maintain a few lineinfile directives. – Server Fault May 9 '19 at 14:18
3

The play below does what is requested.

- replace:
    path: test.xml
    regexp: '<user>admin@localhost<\/user>'
    replace: |-
      <user>user1@somedomain</user>
        <user>user2@somedomain</user>
        <user>user3@somedomain</user>

Next example below shows how to replace the whole sadmin section

- replace:
    path: test.xml
    regexp: '(<sadmin>[\s\S]*)</sadmin>'
    replace: |-
      <sadmin>
        <user>user1@somedomain</user>
        <user>user2@somedomain</user>
        <user>user3@somedomain</user>
      </sadmin>
| improve this answer | |
  • That is good but is there a way to match all within the <sadmin>.*</sadmin> block? It would be best to remove whatever exists in between those tags and have ansible rewrite with the wanted values. This helps when re-applying an updated playbook – Server Fault May 8 '19 at 18:26
  • 1
    Sure, I've updated the answer. – Vladimir Botka May 9 '19 at 13:30
  • Thank you! I could not figure out the right regexp to get it working. Yours works great. – Server Fault May 9 '19 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.