Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible: Insert line if not exists

I'm trying insert a line in a property file using ansible. I want to add some property if it does not exist, but not replace it if such property already exists in the file.

I add to my ansible role

- name: add couchbase host to properties
  lineinfile: dest=/database.properties regexp="^couchbase.host"  line="couchbase.host=127.0.0.1"

But this replaces the property value back to 127.0.0.1 if it exists already in the file.

What I'm doing wrong?

like image 596
Pavel Bernshtam Avatar asked Mar 16 '15 11:03

Pavel Bernshtam


People also ask

How do you replace a line in a file Ansible?

You can use the lineinfile Ansible module to achieve that. The regexp option tells the module what will be the content to replace. The line option replaces the previously found content with the new content of your choice. The backrefs option guarantees that if the regexp does not match, the file will be left unchanged.

What does the Lineinfile module do?

Explanation: The purpose of the lineinfile module is to add lines anywhere in a file passed on a pattern.


3 Answers

The lineinfile module ensures the line as defined in line is present in the file and the line is identified by your regexp. So no matter what value your setting already has, it will be overridden by your new line.

If you don't want to override the line you first need to test the content and then apply that condition to the lineinfile module. There is no module for testing the content of a file so you probably need to run grep with a shell command and check the .stdout for content. Something like this (untested):

- name: Test for line
  shell: grep -c "^couchbase.host" /database.properties || true
  register: test_grep

And then apply the condition to your lineinfile task:

- name: add couchbase host to properties
  lineinfile:
    dest: /database.properties
    line: couchbase.host=127.0.0.1
  when: test_grep.stdout == "0"

The regexp then can be removed since you already made sure the line doesn't exist so it never would match.

But maybe you're doing things back to front. Where does that line in the file come from? When you manage your system with Ansible there should be no other mechanisms in place which interfere with the same config files. Maybe you can work around this by adding a default value to your role?

like image 114
udondan Avatar answered Oct 18 '22 05:10

udondan


This is possible by simply using lineinfile and check_mode:

- name: Check if couchbase.host is already defined
  lineinfile:
    state: absent
    path: "/database.properties"
    regexp: "^couchbase.host="
  check_mode: true
  changed_when: false # This just makes things look prettier in the logs
  register: check

- name: Define couchbase.host if undefined
  lineinfile:
    state: present
    path: "/database.properties"
    line: "couchbase.host=127.0.0.1"
  when: check.found == 0

like image 19
Nick Maynard Avatar answered Oct 18 '22 03:10

Nick Maynard


This is the only way I was able to get this to work.

- name: checking for host
  shell: cat /database.properties | grep couchbase.host | wc -l
  register: test_grep

- debug: msg="{{test_grep.stdout}}"

- name: adding license server
  lineinfile: dest=/database.properties line="couchbase.host=127.0.0.1"
  when: test_grep.stdout == "0"
like image 7
kmjackson788 Avatar answered Oct 18 '22 05:10

kmjackson788