Linux – How to use Ansible to conditionally append a line in a file

ansiblelinuxreplace

I'm trying to create an Ansible task that sets up trim/discards. I have a playbook that takes care of everything else (LVM, fstrim), but I can't figure out how to get crypttab configured properly.

I'm trying to use the replace module to append discard to the end of every line that doesn't have discard present, but I can't seem to get the regex right (I think that's my problem anyway).

I have a /etc/crypttab file that looks something like this:

luks-nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn UUID=nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn none discard
luks-nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn UUID=nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn none

And here's the task:

- name: ensure crypttab is configured to issue discards
  replace: dest=/etc/crypttab backup=yes
    regexp='^(.*(?! discard))$'
    replace='\1 discard'

Best Answer

I'm pretty sure your issue is with the regexp. You'll need to move the lookahead assertion in front of the wildcard in order to only match lines that do not end in discard. For example, ^(?!.* discard$)(.*)$.

Once you make that change you'll have an additional problem in that empty lines will match too -- probably undesirable. Use something like ^(?!.* discard$)(.+)$ to fix this issue by matching one or more characters with .+ (instead of zero or more, .*).

Alternatively, you can use a lookbehind assertion, as in ^(.+)(?<! discard)$.