Ansible lineinfile module can be used to insert a line / delete an existing line / replace an existing line. This module would help us a lot when you need to change any configuration parameter or code line from your codebase.
So lets try to understand this in more details by considering various scenarios. I have below content in remote server file. We'll use this file to cover different scenario.
[root@node1 ~]# cat /tmp/textfile
This is line number 1
This is line number 2
This is line number 3
This is line number 4
This is line number 5
[root@node1 ~]#
Scenario 1 : Insert a new line in file
[root@siddhesh ~]# cat lineinfile.yml
- hosts: dbserver
tasks:
- name: insert a new line in textfile
lineinfile:
dest: /tmp/textfile
line: This is line number 6
state: present
create: yes
[root@siddhesh ~]#
Here :
- hosts: dbserver ==> Host Inventory Group On which this action needs to be performed.
- name: insert a new line in textfile ==> Task Description. lineinfile: ==> Load lineinfile module.
dest: /tmp/textfile ==> File Path of remote server
line: This is line number 6 ==> Line to add in dest file
state: present ==> Line should be add or delete. present is for add and absent is for delete. create: yes ==> Used with `state=present'. If specified, the file will be created if it does not already exist. Lets run this playbook and verify on remote server.
[root@siddhesh ~]# ansible-playbook lineinfile.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY [dbserver] *****************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]
TASK [insert a new line in textfile] ********************************************************************************************************************************
changed: [node1.tecgeek.info] => {"backup": "", "changed": true, "msg": "line added"}
PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info : ok=2 changed=1 unreachable=0 failed=0
[root@siddhesh ~]#
Login to remote server verify its file content.
[root@node1 ~]# cat /tmp/textfile
This is line number 1
This is line number 2
This is line number 3
This is line number 4
This is line number 5
This is line number 6
[root@node1 ~]#
Scenario 2 : Insert a new line after specific line.
In above scenario we saw that how to add/append a new line in existing file. In this scenario we'll see how to add a new line after a specific line.
[root@siddhesh ~]# cat lineinfile.yml
- hosts: dbserver
tasks:
- name: insert a new line in textfile
lineinfile:
dest: /tmp/textfile
line: This is random string
insertafter: 'This is line number 2'
state: present
create: yes
[root@siddhesh ~]#
Here : - hosts: dbserver ==> Host Inventory Group On which this action needs to be performed. - name: insert a new line in textfile ==> Task Description. lineinfile: ==> Load lineinfile module. dest: /tmp/textfile ==> File Path of remote server line: This is random string ==> Line to add in dest file insertafter: 'This is line number 2' ==> If specified, the line will be inserted after the last match of specified regular expression. state: present ==> Line should be add or delete. present is for add and absent is for delete. create: yes ==> Used with `state=present'. If specified, the file will be created if it does not already exist.
Lets execute this playbook and verify file at remote server.
[root@siddhesh ~]# ansible-playbook lineinfile.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY [dbserver] *****************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]
TASK [insert a new line in textfile] ********************************************************************************************************************************
changed: [node1.tecgeek.info] => {"backup": "", "changed": true, "msg": "line added"}
PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info : ok=2 changed=1 unreachable=0 failed=0
[root@siddhesh ~]#
On remote server you could see the changes now.
[root@node1 ~]# cat /tmp/textfile
This is line number 1
This is line number 2
This is random string
This is line number 3
This is line number 4
This is line number 5
This is line number 6
[root@node1 ~]#
Scenario 3 : Commenting a line In most of cases you might need to disable certain parameter or piece of code using hash(#)
So to achieve this you can use following method to make this task more easier.
[root@siddhesh ~]# cat lineinfile.yml
- hosts: dbserver
tasks:
- name: insert a new line in textfile
lineinfile:
dest: /tmp/textfile
regexp: '(This is random string)'
line: '#\1'
backrefs: yes
state: present
create: yes
[root@siddhesh ~]#
Here :
- hosts: dbserver ==> Host Inventory Group On which this action needs to be performed. - name: insert a new line in textfile ==> Task Description. lineinfile: ==> Load lineinfile module. dest: /tmp/textfile ==> File Path of remote server regexp: '(This is random string)' ==> The regular expression to look for in every line of the file.
line: '#\1' ==> Replaces the line with ‘#’ followed by what was captured. backrefs: yes ==> If set, line can contain backreferences (both positional and named) that will get populated if the `regexp' matches. state: present ==> Line should be add or delete. present is for add and absent is for delete. create: yes ==> Used with `state=present'. If specified, the file will be created if it does not already exist.
Lets execute this playbook and see the changes in actual file on remote server.
[root@siddhesh ~]# ansible-playbook lineinfile.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY [dbserver] *****************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]
TASK [insert a new line in textfile] ********************************************************************************************************************************
changed: [node1.tecgeek.info] => {"backup": "", "changed": true, "msg": "line replaced"}
PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info : ok=2 changed=1 unreachable=0 failed=0
[root@siddhesh ~]#
Login to remote server and verify the changes.
[root@node1 ~]# cat /tmp/textfile
This is line number 1
This is line number 2
#This is random string
This is line number 3
This is line number 4
This is line number 5
This is line number 6
[root@node1 ~]#
Scenario 4 : Modify multiple file at a same time.
Using with_items we can loop through a list of multiple file hash. This will be very useful when you have to modify multiple files with different content. Lets see how to handle this using ansible module lineinfile.
[root@siddhesh ~]# cat lineinfile.yml
- hosts: dbserver
tasks:
- name: insert a new line in textfile
lineinfile:
dest: "{{ item.dest }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
backrefs: yes
with_items:
- {dest: '/tmp/textfile', regexp: 'This is line number 5', line: 'line number 5 modified due to security reason'}
- {dest: '/tmp/user', regexp: 'centos', line: 'opensuse'}
[root@siddhesh ~]#
Here :
- hosts: dbserver ==> Host Inventory Group On which this action needs to be performed. - name: insert a new line in textfile ==> Task Description. lineinfile: ==> Load lineinfile module. dest: "{{ item.dest }}" ==> Destination path of with_items loop
regexp: "{{ item.regexp }}" ==> The regular expression to look for in every line of the file of with_items loop. line: "{{ item.line }}" ==> Line to replace with match regexp of with_items loop. backrefs: yes ==> If set, line can contain backreferences (both positional and named) that will get populated if the `regexp' matches. with_items: ==> with_items loop with multiple hashes like file path, regexp, line to replace etc.
So lets execute this quiet complicated but very useful playbook.
[root@siddhesh ~]# ansible-playbook lineinfile.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY [dbserver] *****************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]
TASK [insert a new line in textfile] ********************************************************************************************************************************
changed: [node1.tecgeek.info] => (item={u'dest': u'/tmp/textfile', u'regexp': u'This is line number 5', u'line': u'line number 5 modified due to security reason'}) => {"backup": "", "changed": true, "item": {"dest": "/tmp/textfile", "line": "line number 5 modified due to security reason", "regexp": "This is line number 5"}, "msg": "line replaced"}
changed: [node1.tecgeek.info] => (item={u'dest': u'/tmp/user', u'regexp': u'centos', u'line': u'opensuse'}) => {"backup": "", "changed": true, "item": {"dest": "/tmp/user", "line": "opensuse", "regexp": "centos"}, "msg": "line replaced"}
PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info : ok=2 changed=1 unreachable=0 failed=0
[root@siddhesh ~]#
On remote server you can verify the changes.
[root@node1 ~]# cat /tmp/user
siddhesh
linux
opensuse
redhat
[root@node1 ~]#
[root@node1 ~]# cat /tmp/textfile
This is line number 1
This is line number 2
#This is random string
This is line number 3
This is line number 4
line number 5 modified due to security reason
This is line number 6
[root@node1 ~]#
Comments