Ansible Lineinfile Module: Manage Lines in Text Files
In this tutorial, we'll explore the Ansible lineinfile module, a powerful tool for managing lines in text files.
Whether you're updating configuration files or ensuring specific lines are present or absent, lineinfile provides a straightforward way to automate these tasks.
We'll start with an overview of this Ansible module's syntax and usage, then dive into practical examples that illustrate its capabilities.
What is Ansible Lineinfile Module?
The lineinfile module is used to ensure a particular line is present or absent in a file. It can also be used to replace existing lines that match a certain pattern. This module is especially useful for managing configuration files, where specific lines must be added, modified, or removed.
Here’s the basic syntax for the lineinfile module:
- name: Ensure a line is present in a file
ansible.builtin.lineinfile:
path: /path/to/file
line: 'text to be added'
This simple example ensures that a specific line of text is present in a given file. The module checks the file at the specified path and adds the line if it's not already present. This basic usage can be extended with various parameters to handle more complex scenarios.
Here is the explanation:
path
: The file to modify.line
: The line to insert or ensure is present.state
: If set to absent, the line will be removed.regexp
: A regular expression to match the line that needs to be replaced.insertafter or insertbefore
: Specifies where to insert the line if it’s not found.
Let's look at some practical examples to understand how lineinfile can be used in different scenarios.
Example 1: Ensuring a line is present
In this example, we'll ensure that a specific configuration line is present in a file.
---
- name: Ensuring a Line is Present
hosts: all
tasks:
- name: Ensure the timezone is set in /etc/timezone
ansible.builtin.lineinfile:
path: /etc/timezone
line: 'Asia/Kolkata'
This task will check the /etc/timezone
file and add Asia/Kolkata
if it’s not already present. This is useful for setting system-wide configurations that must be consistent across multiple machines.
By ensuring the line is present, you can standardize configurations and avoid manual errors. This is particularly useful in large environments where consistency is key.
Example 2: Removing a line
Sometimes, you need to ensure a specific line is not present in a file. You can use the state: absent
parameter to achieve this.
---
- name: Removing a Line
hosts: all
tasks:
- name: Remove the deprecated setting from config
ansible.builtin.lineinfile:
path: /etc/config_file
line: 'DeprecatedSetting=true'
state: absent
This task will remove the line DeprecatedSetting=true
from /etc/config_file
if it exists. This is helpful for cleaning up obsolete or incorrect settings from configuration files.
Removing deprecated settings helps maintain clean and up-to-date configuration files, ensuring that only relevant and necessary configurations are applied.
Example 3: Replacing a line matching a pattern
You can replace lines that match a certain pattern using the regexp
parameter.
---
- name: Replacing a Line Matching a Pattern
hosts: all
tasks:
- name: Update the max_connections setting in my.cnf
ansible.builtin.lineinfile:
path: /etc/my.cnf
regexp: '^max_connections'
line: 'max_connections = 500'
This task will search for a line starting with max_connections
in /etc/my.cnf
and replace it with max_connections = 500
. This is useful for updating configurations to meet new requirements.
By using patterns, you can target specific lines for replacement, ensuring that only the intended lines are modified. This adds flexibility and precision to your automation scripts.
Example 4: Inserting a line after a specific pattern
You might need to insert a line after a specific line or pattern. Use the insertafter
parameter for this purpose.
---
- name: Inserting a Line After a Specific Pattern
hosts: all
tasks:
- name: Add a new repository after the existing repositories
ansible.builtin.lineinfile:
path: /etc/apt/sources.list
line: 'deb http://example.com/repo ubuntu main'
insertafter: '^# End of file'
This task will insert the new repository line after the line matching the pattern ^# End of file
. This is useful for adding new configurations in a specific order.
Inserting lines in the correct order ensures that your configuration files remain organized and that new settings are applied in the desired context.
Example 5: Handling multiple lines with lineinfile module
While lineinfile is designed for single lines, you can manage multiple lines by running the module multiple times or using loops.
---
- name: Handling Multiple Lines with Lineinfile
hosts: all
tasks:
- name: Ensure multiple lines are present
ansible.builtin.lineinfile:
path: /etc/my.cnf
line: "{{ item }}"
with_items:
- 'max_connections = 500'
- 'bind-address = 0.0.0.0'
This task ensures that both max_connections
and bind-address
lines are present in /etc/my.cnf
. Using loops allows you to apply multiple changes in a single task.
Handling multiple lines efficiently reduces the complexity of your playbooks and ensures that all necessary configurations are applied in one go.
Example 6: Adding a line before a specific pattern
Sometimes you may want to insert a line before a certain pattern in a file. Use the insertbefore
parameter for this purpose.
---
- name: Adding a Line Before a Specific Pattern
hosts: all
tasks:
- name: Add a comment line before the server block in nginx config
ansible.builtin.lineinfile:
path: /etc/nginx/nginx.conf
line: '# Added by Ansible'
insertbefore: '^server {'
This task will add the line # Added by Ansible before any line that starts with server {
in the /etc/nginx/nginx.conf
file. This helps in adding comments or directives in a specific place in configuration files.
Adding lines before specific patterns helps you place new configurations exactly where they are needed, maintaining the logical flow of the file.
Example 7: Ensuring a line in a file that does not exist yet
You can create a file if it doesn’t exist and ensure a line is present in it.
---
- name: Ensuring a Line in a File That Does Not Exist Yet
hosts: all
tasks:
- name: Ensure a line in a file that does not exist yet
ansible.builtin.lineinfile:
path: /etc/new_config_file
line: 'InitialSetting=true'
create: yes
This task ensures that the file /etc/new_config_file
exists and contains the line InitialSetting=true
. If the file does not exist, it will be created. This is useful for initializing new configuration files.
Creating files on the fly ensures that all necessary configurations are applied even if the files are missing, making your automation scripts more robust.
Example 8: Ensuring a line exists with a specific owner and permissions
You can also ensure that a file has a specific owner and permissions while ensuring a line is present.
---
- name: Ensuring a Line Exists with a Specific Owner and Permissions
hosts: all
tasks:
- name: Ensure a line is present with specific owner and permissions
ansible.builtin.lineinfile:
path: /etc/some_config
line: 'SomeImportantSetting=yes'
notify:
- set_permissions
handlers:
- name: set_permissions
ansible.builtin.file:
path: /etc/some_config
owner: root
group: root
mode: '0644'
This task ensures the line SomeImportantSetting=yes
is present in /etc/some_config
, and it sets the owner to root and permissions to 0644 using a handler. This ensures that the file has the correct ownership and permissions.
Setting the correct permissions and ownership ensures that the file is secure and accessible only by authorized users.
Conclusion
In this article, I covered the basics of the Ansible lineinfile module, including its syntax and key parameters.
You also looked at several practical examples, such as ensuring a line is present, removing a line, replacing a line matching a pattern, and inserting a line after a specific pattern. You also explored advanced scenarios like adding lines before specific patterns, setting file permissions, and creating new files with specific lines.