0

I need to replace multiple configuration lines from one file using ansible. For this, I have used lineinfile module with regexp.

The play looks like this:

- name: Changing parameters in {{ rt_2_dir }}/config.xml
  lineinfile:
    path: "{{ ais_dir }}/Instances/{{ rt_2_dir }}/config.xml"
    regexp: '{{item.From}}'
    line: '{{item.To}}'
    state: present
  with_items:
    - { From: '  <Configuration_Entry Key="Java Max Heap Size (MB)" Value="4096"/>', To: '  <Configuration_Entry Key="Java Max Heap Size (MB)" Value="16384"/>' }
    - { From: '  <Configuration_Entry Key="Maximum number of queue listener threads (dialogs)" Value="20"/>', To: '  <Configuration_Entry Key="Maximum number of queue listener threads (dialogs)" Value="60"/>' }
    - { From: '  <Configuration_Entry Key="Additional JVM Settings" Value="-Xms512M;-Xss256K;-XX:+UseConcMarkSweepGC;-XX:+UseTLAB;-Xrs"/>', To: '  <Configuration_Entry Key="Additional JVM Settings" Value="-Xms8192M;-Xss1024K;-XX:+UseParallelGC;-XX:+UseCMSInitiatingOccupancyOnly;-XX:CMSInitiatingOccupancyFraction=80;-XX:+UseTLAB;-Xrs;-Dorg.apache.activemq.SERIALIZABLE_PACKAGES=*;-XX:-UseGCLogFileRotation;-XX:GCLogFileSize=8M;-XX:-PrintGCTimeStamps;-verbose:gc;-Xloggc:/path/to/server/instance/logs/gclog.out;"/>' }

However, when running the the play, instead of replacing the lines, it adds the information at the end of the config file.

If I am replacing this 3 lines with the one below, it replaces it.

- { From: '  <Configuration_Entry Key="Add-On - Enable Geographic Add-On" Value="0"/>', To: '  <Configuration_Entry Key="Add-On - Enable Geographic Add-On" Value="1"/>' }
- { From: '  <Configuration_Entry Key="Add-On - Enable Financial Institutions" Value="0"/>', To: '  <Configuration_Entry Key="Add-On - Enable Financial Institutions" Value="1"/>' }
- { From: '  <Configuration_Entry Key="Add-On - Enable IP Enrichment" Value="0"/>', To: '  <Configuration_Entry Key="Add-On - Enable IP Enrichment" Value="1"/>' }

First I thought that there might be an issue with the parameters that are written at From:, thinking that they might not be identical in the config file, but when I looked in the config file, they exist and I have even copied the values from the config file as they were.

I am starting to think that some characters such as minus, semicolon, plus might be the issue here, because other lines are not getting impacted if there are no characters like these in From:.

Can someone help me adjust the code a bit so that these 3 lines get replaced properly?

Thank you!

4
  • Could you try using search_string in place of regexp? Since you seem to want to search using a fixed string (not a regular expression), it would make more sense to use search_string.
    – Kusalananda
    Commented Aug 5, 2022 at 9:23
  • Unfortunately, that doesn't work - it errors in failed: [servera.com] (item={'From': ' ', 'To': ' '}) => {"ansible_loop_var": "item", "changed": false, "item": {"From": " ", "To": " "}, "msg": "Unsupported parameters for (lineinfile) module: search_string Supported parameters include: attributes, backrefs, backup, create, firstmatch, group, insertafter, insertbefore, line, mode, owner, path, regexp, selevel, serole, setype, seuser, state, unsafe_writes, validate"}
    – JugaruGabi
    Commented Aug 5, 2022 at 9:32
  • Yes, it was added in verison 2.11. What release of Ansible are you running?
    – Kusalananda
    Commented Aug 5, 2022 at 9:35
  • Unfortunately I cannot tell for sure... I am using this under a web-based portal and I cannot find out the exact version of ansible.
    – JugaruGabi
    Commented Aug 5, 2022 at 9:44

1 Answer 1

3

The issue is that each of the From strings that you are trying to match contains characters that are special when the strings are interpreted as regular expressions.

The first and second string contains ( and ), while the third string contains +. Each of these characters needs to be escaped with \ to be taken literally when using the strings as regular expressions.

Normally, one would want to use a manner of matching these strings that do not use them as regular expressions but as literal strings. In Ansible 2.11 and later, one does this by using search_string in place of regexp with the ansible.builtin.lineinfile module (see the relevant Ansible documentation).

If you are on a too old release of Ansible and therefore need to use regexp, then escape the special characters in the From string as mentioned above (note that the To strings don't need changing):

with_items:
    - { From: '  <Configuration_Entry Key="Java Max Heap Size \(MB\)" Value="4096"/>', To: '  <Configuration_Entry Key="Java Max Heap Size (MB)" Value="16384"/>' }
    - { From: '  <Configuration_Entry Key="Maximum number of queue listener threads \(dialogs\)" Value="20"/>', To: '  <Configuration_Entry Key="Maximum number of queue listener threads (dialogs)" Value="60"/>' }
    - { From: '  <Configuration_Entry Key="Additional JVM Settings" Value="-Xms512M;-Xss256K;-XX:\+UseConcMarkSweepGC;-XX:\+UseTLAB;-Xrs"/>', To: '  <Configuration_Entry Key="Additional JVM Settings" Value="-Xms8192M;-Xss1024K;-XX:+UseParallelGC;-XX:+UseCMSInitiatingOccupancyOnly;-XX:CMSInitiatingOccupancyFraction=80;-XX:+UseTLAB;-Xrs;-Dorg.apache.activemq.SERIALIZABLE_PACKAGES=*;-XX:-UseGCLogFileRotation;-XX:GCLogFileSize=8M;-XX:-PrintGCTimeStamps;-verbose:gc;-Xloggc:/path/to/server/instance/logs/gclog.out;"/>' }

The issue is similar to looking for lines with grep containing a literal string that happens to be a valid regular expression, such as .*. For this reason, grep has a -F option that stops the utility from interpreting the given pattern as a regular expression.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .