Ansible is a widely used automation tool that can manage hundreds of nodes in one go. Ansible has lots of great features, and one of them is its ability to manage a single line within a file on remote nodes using the Ansible lineinfile module.
The Ansible lineinfile module is a module that performs various actions on a single line on a file, such as replacing a line, updating a line, or adding a particular line.
In this tutorial, you’re going to learn what the Ansible lineinfile module is, how it works, and how to use it to manage text files.
Prerequisites
This post will be a step-by-step tutorial on the Ansible lineinfile module. If you’d like to follow along, be sure you have the following in place:
- An Ansible controller host – This tutorial will be using Ansible v2.9.24 on an Ubuntu 18.04.5 LTS machine.
- A remote computer to run commands. You’ll need an inventory file set up and one or more hosts already configured to run Ansible command and playbooks on. The remote Linux computer will be called myserver, and the tutorial will use an inventory group called web.
- Apache should already be installed on the remote computer if you’d like to follow along with the tutorial exactly.
Modifying a Text File with the Ansible lineinfile module.
Let’s begin this tutorial by running Ansible lineinfile module using the ad hoc commands. Ad hoc commands are a quick way to test or run a single command on a remote host.
Log onto your Ansible controller and run the following command. This command uses the lineinfile module (-m
) to connect to the web machine and pass an argument (-a
) which is the command to execute.
In this instance, the lineinfile module updates the localhost entry by mapping IP-address 127.0.0.1
with myapache
in the/etc/hosts file. By mapping the 127.0.0.1
with myapache
allows you to navigate to the apache test page locally on HTTP://myapache:80
path
denotes the file location.regexp
finds the regular expression, if any, in the file and updates with127.0.0.1 myapache
specified in theline
parameter.- –become flag allows you to run the command as a privileged user.
- The
web
is the inventory group that is a collection of all servers. ansible.builtin.lineinfile
or simply lineinfile is the module name.
ansible web -m ansible.builtin.lineinfile -a "path=/etc/hosts regexp='^127\.0\.0\.1' line='127.0.0.1 myapache' state=present" --become
After you execute the command, you should see a CHANGED message that confirms that the line has been successfully updated on the remote host.
Log in to the remote node using an SSH client and verify if the /etc/hosts file has been updated with the new value using the cat
command.
As you can see below, the localhost entry has successfully been updated with 127.0.0.1 myapache
on the remote machine.
Modifying Multiple Text Files Within a Playbook
Working with single ad hoc command to manage lines on a remote machine may be OK, but it’s going to be difficult if you have lines in multiple files or multiple lines in a file to manage. Instead of using ad-hoc commands, consider using Ansible lineinfile module within the playbook using the ansible-playbook command.
Now, let’s learn how to use Ansible lineinfile module within the playbook and modify few lines.
Assuming you’re already logged into Ansible controller host:
1. Create a directory called ansible_lineinfile_module_demo in your home directory. This directory will contain the playbook you’ll use to invoke the lineinfile module.
mkdir ~/ansible_lineinfile_module_demo
cd ~/ansible_lineinfile_module_demo
2. Create another file called my_playbook.yml in the ~/ansible_lineinfile_module_demo directory and paste in the following YAML playbook contents. This playbook has multiple tasks that use Ansible lineinefile
module to manage lines of different config files for Apache on the remote machine.
The playbook below contains the following tasks:
1. Checks if ADMIN
is present in /etc/sudoers file; if not, the task adds it.
2. Ensures the Apache default is listening on 8080 within the /etc/apache2/ports.conf file; if it finds any other port lineinfile module updates it to port 8080
. Similarly under /etc/apache2/apache2.conf file, it updates the MaxKeepAliveRequests
to 1000 and KeepAliveTimeout
to 100.
3. Adds the line with the text “Hello This is my Apache Page” at the end of the index.html
page on the remotes server under the /var/www/html directory.
Ansible playbooks are written in YAML. To learn more about YAML, click here
---
- name: Ansible lineinfile module example
# Defining the remote server where Ansible lineinfile module will take effect
hosts: web
remote_user: ubuntu # Using Remote host as ubuntu
become: true
tasks:
# (Task-1) Checking the Sudoers file if Admins are allowed to perform all operations
- name: Validate the sudoers file before saving
ansible.builtin.lineinfile:
path: /etc/sudoers
state: present
regexp: '^%ADMIN ALL='
line: '%ADMIN ALL=(ALL) NOPASSWD: ALL'
# (Task-2) Updating the Apache Default Port to 8080
- name: Ensure the default Apache port is 8080
ansible.builtin.lineinfile:
path: /etc/apache2/ports.conf
regexp: '^Listen '
insertafter: '^#Listen '
line: Listen 8080
# (Task-3) Adding the Line at the end of the html page Hello This is my Apache Page
- name: Add a line to a file if the file does not exist
ansible.builtin.lineinfile:
path: /var/www/html/index.html
line: Hello This is my Apache Page
create: yes
# (Task-4) Checking the Sudoers file if Admins are allowed to perform all operations
- name: Ensure MaxKeepAliveRequests is set to greater than 100
ansible.builtin.lineinfile:
path: /etc/apache2/apache2.conf
regexp: '^MaxKeepAliveRequests'
line: MaxKeepAliveRequests=1000
# (Task-5) Checking the Sudoers file if Admins are allowed to perform all operations
- name: Ensure KeepAliveTimeout is set to greater than 50
ansible.builtin.lineinfile:
path: /etc/apache2/apache2.conf
regexp: '^KeepAliveTimeout'
line: KeepAliveTimeout=100
3. Now, invoke the playbook and execute the tasks using the ansible-playbook
command to add or update all the lines defined in the playbook on the remote host.
ansible-playbook my_playbook.yml
Below, you can see that the TASK has a status of changed, meaning the remote host wasn’t in the proper state and was modified to run the command. For that TASK which has OK status, shows they don’t require any changes.
4. Next, SSH into the remote host using your favorite SSH client.
5. Finally, verify if all the lines defined in the my_playbook.yml are updated or added on the remote host using the cat
command.
# To verify if admin is present with full privileges and if not add it
cat /etc/sudoers
# To verify the MaxKeepAliveRequests and KeepAliveTimeout have been updated to 1000 and 100, respectively.
cat /etc/apache2/apache.config | grep Alive
# To verify if Apache is listening on Port 8080
cat /etc/apache2/ports.config
The below screenshot confirms that the admin
is already added in the sudoers file.
Again, the below screenshot confirms that the apache is listening on Port 8080
by default.
Finally, verify the MaxKeepAliveRequests
and KeepAliveTimeout
if they have been updated to 1000 and 100, respectively.
Conclusion
The Ansible lineinfile module is a great way to modify text files on remote hosts. The module provides a great way to add, remove and modify lines in text files within your playbooks.
What other use cases do you see would benefit from the Ansible lineinfile module?