Eunito
Eunito

Reputation: 436

How to add an entry in a file (only if it doesn't exist) using Ansible

I'm trying to add a json entry into a file in a specific position using Ansible and lineinfile + insertbefore. This is a mock of the original file:

const var = 
{
    "values": [
        {
            "entry1":500,
            "entry2": "test001",
            "entry3": true
        },
        {
            "entry1":3,
            "entry2": "test002",
            "entry3": false
        }
    ]
};

The ansible script is this:

- name: script description 1
  lineinfile:
     dest: /destinationPATH/file.xpto
     insertbefore: "]"
     line: "\t\t,\t\t{\n\t\t\t'entry1':0,\n\t\t\t'entry2': 'ansible entry',\n\t\t\t'entry3': true\n\t\t}\n"
     state: present
     backup: yes

On the first try it works fine, adding the expected entry!

const var = 
{
    "values": [
        {
            "entry1": 500,
            "entry2": "test001",
            "entry3": true
        },
        {
            "entry1": 3,
            "entry2": "test002",
            "entry3": false
        }
        ,
        {
            "entry1": 0,
            "entry2": "ansible entry",
            "entry3": true
        }
    ]
};

The problem is that if I run twice, ... it adds that entry again...

const var = 
{
    "values": [
        {
            "entry1": 500,
            "entry2": "test001",
            "entry3": true
        },
        {
            "entry1": 3,
            "entry2": "test002",
            "entry3": false
        }
        ,
        {
            "entry1": 0,
            "entry2": "ansible entry",
            "entry3": true
        }
        ,
        {
            "entry1": 0,
            "entry2": "ansible entry",
            "entry3": true
        }
    ]
};

Tryed

- name: script description 2
    become: yes
    become_method: sudo
    lineinfile:
        dest: /destinationPATH/file.xpto
        insertbefore: "]"
        line: "\t\t,\t\t{\n\t\t\t'entry1':0,\n\t\t\t'entry2': 'ansible entry',\n\t\t\t'entry3': true\n\t\t}\n"
        backup: yes
    check_mode: yes

and now the file isn't even changed... Is there any way I can evaluate if that line exists in the file and if that is true then ansible adds it?

Upvotes: 0

Views: 827

Answers (1)

Thomas Hirsch
Thomas Hirsch

Reputation: 2308

I'd break down the problem into two tasks.
I am assuming that your ansible entry is a unique string, that you can search for in the file.
So first, I would check if the entry exists in the file at all, like this:

 - name: Check if the file contains the entry
   shell: cat /destinationPATH/file.xpto | grep "ansible entry"
   become: yes
   become_method: sudo
   failed_when: false
   register: grep_result

The grep_result is a dictionary, that contains among other things the return code of the shell command, i.e. other than 0 in case it failed, which means the entry was not present.
failed_when: false makes it so that the play does not abort if that happens.

Then you could make your task dependend on the result using when, like this:

- name: script description 2
  become: yes
  become_method: sudo
  lineinfile:
    dest: /destinationPATH/file.xpto
    insertbefore: "]"
    line: "\t\t,\t\t{\n\t\t\t'entry1':0,\n\t\t\t'entry2': 'ansible entry',\n\t\t\t'entry3': true\n\t\t}\n"
    backup: yes
  when: grep_result.rc > 0

Upvotes: 1

Related Questions