Can ansible iterate through lines in a file?

I have a list of lines I want to add to a file on the target system if they don’t exist. I don’t want to wholesale overwrite the file, and I don’t want to write dozens of lineinfile: statements.

Is it possible to do the equivalent of:

while read line; do

if grep “$line” /target/file >/dev/null 2>&1 ; then : ; else echo $line >> /target/file; fi
done < /source/file

You can use lineinfile and with_items

Ex:

- name: Add lines
  lineinfile: dest=/some/file line={{ item }}
  with_items:
     - "add a line"
     - "another line"
     - "and so on"

I’ve also run into this issue and haven’t picked the best way to deal with it yet.

You can always run that command via the shell module. Occasionally commands get a little gross and you’ll have to add so many escape characters and quotes that even you can’t tell what’s going on. If that happens, you could consider adding the command as a file or template, pushing that to a host, running it and then deleting it (if you so choose).

All of those are a little clunky and feel pretty anti-Ansible. It’s goal is to be idempotent and with a command like that, you are breaking this canon.

Out of curiosity, what are you trying to add to what?

Dozens of lines to the audit log configuration.

I probably will just push a script and run it. But you’re right… it’s “un-ansible-like” :slight_smile:

But so long as our scripts can be run idempotently, it isn’t a total hack :slight_smile:

If you just call lineinfile, where will it write them? At the end? What if your target file has some kind of terminator, can you do a blanket insertbefore or insertafter? I’m not really grokking the concept of ‘backrefs’.

Calling lineinfile without any other arguments like my example would insert the lines at the end of the file if they don’t already exist.

You can modify this behavior using insertbefore and insertafter, both take regex as a value, so you can determine certain sections to add the new lines to… using maybe existing lines in the file or maybe placeholder comments?

Backrefs are used to replace specific parts of an existing line using the regex + line values.