1

I have an ansible task that writes 2 lines into journald.conf, however it doesn't perform idempotency when running again.

I have seen the following questions that didn't work for me:

My regex seems to be okay, you can see below my task:

- name: set cpu affinity settings in systemd
  lineinfile:
    dest: /etc/systemd/journald.conf
    line: "{{ item.key }}={{ item.value }}"
    regexp: "^#?{{ item.value }}"
    state: present
  with_dict:
    RateLimitIntervalSec: 0
    RateLimitBurst: 0
  tags: journald
  notify: restart journald

The expected behavior should be: keep the commented line and add new ones at the end of the file with the items in the list, unless the uncommented lines already exists.

My file journald.conf file is like this:

[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=1000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K
RateLimitIntervalSec=0
RateLimitBurst=0
RateLimitIntervalSec=0
RateLimitBurst=0
RateLimitIntervalSec=0
RateLimitBurst=0
RateLimitIntervalSec=0
RateLimitBurst=0

I tried to use the parameter backrefs: yes as suggested in above mentioned articles, but it performs idempotency every time, even when there is no any uncommented line.

Do you guys have any suggestions?

I'm using ansible 2.9.0

Daniel
  • 19
  • 3
  • Your regex is matching the value at the beginning of the line instead of the key. It will never match. So it is adding a new line on every run. – Zeitounator Jul 31 '21 at 19:41
  • In case my previous comment was not clear enough => `regexp: "^#?{{ item.key }}"`. Note that this will not match commented lines with space(s) between the hash sign and the variable name, nor those with several hashes in front. Moreover, if your key is used as a prefix to an other var (e.g. `Storage`, `StoragePath`, ...), only the first found line will be matched (and replaced). As a safe approach, I would use something like => `regexp: "^#*\\s*{{ item.key }}\\s*="`. – Zeitounator Aug 01 '21 at 07:43
  • Actually I don't have any space or character after the `#`, I just found out that my problem is because my regex try to find the `item.value` instead of `item.key`. Still, your suggestion is very appreciated and I'm sure it will be helpful for another situation soon – Daniel Aug 01 '21 at 17:47

1 Answers1

1

I'd suggest an alternative approach - use the ini_file module, as settings in journald.conf are INI style key=value (with a section as well). This will simplify the task required and be idempotent as well.

Example:

    - name: set cpu affinity settings in systemd
      ini_file:
        path: /etc/systemd/journald.conf
        section: Journal
        option: "{{ item.key }}"
        value: "{{ item.value }}"
        no_extra_spaces: yes
      with_dict:
        RateLimitIntervalSec: 0
        RateLimitBurst: 0

Note: If you want a reference of settings prior to change, add backup: yes to the task.

seshadri_c
  • 6,906
  • 2
  • 10
  • 24
  • It's a viable approach! However I'd like to keep the old line commented and add these new ones at the end of the file, is it possible with this module? I have tried your code above and it replaces the old values that were commented. – Daniel Jul 31 '21 at 18:18
  • This module adds entries based on the given `section`, and not necessarily at EOF, also any existing settings (even commented) will be modified as specified in `option` and `value`. But it takes away the chore of forming a proper regex to maintain idempotency. – seshadri_c Jul 31 '21 at 18:32
  • 1
    I see, anyway this already works for me, and it's a nice approach when using INI style files, thank you! – Daniel Jul 31 '21 at 18:47