Vishal Kotcherlakota Vishal Kotcherlakota - 2 months ago 29
Linux Question

How do I append a large amount of text to a file using Ansible?

Our application creates a lot of definitions in

/etc/services
. We keep a
services
file handy with all these definitions so that we can just pipe them into
/etc/services
like this:

cp /etc/services /etc/services.stock
cat /path/to/build/services >> /etc/services


It works, but it's not idempotent i.e. running these commands repeatedly will cause the services file to get appended with the info again.

As I work through our Ansible playbooks, I'm trying to figure out how to do this. I could so something like this:

- command: "cat /path/to/build/services >> /etc/services"


but I don't want it to run every time I run the playbook.

Another option is to do something like this:

- name: add services
lineinfile:
state: present
insertafter: EOF
dest: /etc/services
line: "{{ item }}"
with_items:
- line 1
- line 2
- line 3
- line 4
- ...


but this is really slow, because it does each line individually.

Is there a better way? Templates don't help, because they'd totally overwrite the services file, which seems a little rude.

Answer

blockinfile is a native, idempotent module to ensure a specified set of lines is present (absent) in a file.

Example:

- name: add services
  blockinfile: 
    state: present
    insertafter: EOF
    dest: /etc/services
    marker: "<!-- add services ANSIBLE MANAGED BLOCK -->"
    content: |
      line 1
      line 2
      line 3
Comments