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.

✍️
Author: Hitesh Jethwa has more than 15+ years of experience with Linux system administration and DevOps. He likes to explain complicated topics in easy to understand way.