AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible lineinfile Module: Add, Replace, Remove Lines in Files (Complete Guide)

By Luca Berton · Published 2024-01-01 · Category: database-automation

How to use Ansible lineinfile module to manage lines in configuration files. Add, replace, remove, and insert lines with regex.

Ansible lineinfile Module: Add, Replace, Remove Lines in Files (Complete Guide)

The ansible.builtin.lineinfile module ensures a specific line exists (or doesn't exist) in a file. It's ideal for managing individual settings in configuration files without templating the entire file.

See also: Ansible lineinfile Module Cookbook: 25 Practical Examples

Add a Line

- name: Add line to file
  ansible.builtin.lineinfile:
    path: /etc/environment
    line: 'JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64'

If the line already exists, nothing changes (idempotent).

Replace a Line (Regex)

- name: Set SSH port to 2222
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?Port\s+'
    line: 'Port 2222'
  notify: restart sshd

- name: Disable root login ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^#?PermitRootLogin' line: 'PermitRootLogin no' notify: restart sshd

The regexp finds the existing line. The line parameter replaces it.

See also: Publishing Ansible Collections to Ansible Galaxy and Automation Hub

Remove a Line

- name: Remove a line
  ansible.builtin.lineinfile:
    path: /etc/hosts
    regexp: '^192\.168\.1\.100\s+oldserver'
    state: absent

- name: Remove all comments ansible.builtin.lineinfile: path: /etc/myapp.conf regexp: '^\s*#' state: absent

Insert at Specific Position

After a Line

- name: Add nameserver after existing one
  ansible.builtin.lineinfile:
    path: /etc/resolv.conf
    insertafter: '^nameserver'
    line: 'nameserver 8.8.4.4'

Before a Line

- name: Add comment before setting
  ansible.builtin.lineinfile:
    path: /etc/myapp.conf
    insertbefore: '^max_connections'
    line: '# Database connection settings'

At Beginning or End

# At the beginning
- name: Add shebang at top
  ansible.builtin.lineinfile:
    path: /opt/script.sh
    insertbefore: BOF
    line: '#!/bin/bash'

# At the end (default behavior) - name: Append to file ansible.builtin.lineinfile: path: /etc/hosts line: '10.0.0.50 appserver'

See also: Ansible on Debian 11 Bullseye: OpenSSH Hardening Complete Guide

Set Permissions and Ownership

- name: Add line with specific permissions
  ansible.builtin.lineinfile:
    path: /etc/sudoers.d/deploy
    line: 'deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp'
    create: true
    owner: root
    group: root
    mode: '0440'
    validate: 'visudo -cf %s'

Create File if Missing

- name: Ensure config exists with setting
  ansible.builtin.lineinfile:
    path: /etc/myapp/custom.conf
    line: 'log_level=info'
    create: true
    owner: appuser
    mode: '0644'

Validate Before Writing

- name: Update sudoers safely
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    regexp: '^%admin'
    line: '%admin ALL=(ALL) ALL'
    validate: 'visudo -cf %s'

- name: Update sshd_config safely ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^#?MaxAuthTries' line: 'MaxAuthTries 3' validate: 'sshd -t -f %s'

Common Use Cases

Configure SSH Security

- name: Harden SSH configuration
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  loop:
    - { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
    - { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
    - { regexp: '^#?X11Forwarding', line: 'X11Forwarding no' }
    - { regexp: '^#?MaxAuthTries', line: 'MaxAuthTries 3' }
    - { regexp: '^#?ClientAliveInterval', line: 'ClientAliveInterval 300' }
  notify: restart sshd

Manage /etc/hosts

- name: Add host entries
  ansible.builtin.lineinfile:
    path: /etc/hosts
    regexp: '.*\s+{{ item.name }}$'
    line: "{{ item.ip }} {{ item.name }}"
  loop:
    - { ip: '10.0.0.10', name: 'web01' }
    - { ip: '10.0.0.20', name: 'db01' }
    - { ip: '10.0.0.30', name: 'cache01' }

Set Environment Variables

- name: Set environment variables
  ansible.builtin.lineinfile:
    path: /etc/environment
    regexp: '^{{ item.key }}='
    line: '{{ item.key }}={{ item.value }}'
  loop:
    - { key: 'JAVA_HOME', value: '/usr/lib/jvm/java-21-openjdk-amd64' }
    - { key: 'NODE_ENV', value: 'production' }
    - { key: 'APP_PORT', value: '8080' }

Manage Kernel Parameters

- name: Set sysctl parameters
  ansible.builtin.lineinfile:
    path: /etc/sysctl.conf
    regexp: '^#?{{ item.key }}\s*='
    line: '{{ item.key }} = {{ item.value }}'
  loop:
    - { key: 'net.ipv4.ip_forward', value: '1' }
    - { key: 'vm.swappiness', value: '10' }
  notify: reload sysctl

lineinfile vs replace vs template

| Module | Use When | |--------|----------| | lineinfile | Managing single lines (key=value settings) | | replace | Replacing text patterns across multiple lines | | template | Managing entire file content from a Jinja2 template | | blockinfile | Managing a block of multiple lines |

Backup Before Changes

- name: Modify config with backup
  ansible.builtin.lineinfile:
    path: /etc/nginx/nginx.conf
    regexp: '^\s*worker_processes'
    line: '    worker_processes auto;'
    backup: true

FAQ

How do I add a line to a file in Ansible?

Use ansible.builtin.lineinfile with path and line parameters. The module adds the line at the end of the file if it doesn't already exist. Set create: true to create the file if missing.

How do I replace a line in Ansible?

Use regexp to match the existing line and line to specify the replacement: ansible.builtin.lineinfile: path=/etc/config regexp='^old_setting' line='new_setting=value'.

What is the difference between lineinfile and replace?

lineinfile manages a single line — ensuring it exists, replacing it, or removing it. replace does regex find-and-replace across the entire file and can handle multi-line patterns.

How do I insert a line after a specific line?

Use insertafter: 'regex_pattern' to place the new line after the first match. Use insertbefore: 'regex_pattern' for before. Use BOF/EOF for beginning/end of file.

Is lineinfile idempotent?

Yes. If the line already exists (matching either line or regexp), no changes are made. Running the same task multiple times produces the same result.

Conclusion

ansible.builtin.lineinfile is essential for managing configuration files line by line. Use regexp for replacements, insertafter/insertbefore for positioning, and validate for safe changes to critical files like sudoers and sshd_config.

Related Articles

Ansible replace Module: Regex Find and ReplaceAnsible blockinfile Module: Manage Text BlocksAnsible template Module: Deploy Configuration Files

Category: database-automation

Browse all Ansible tutorials · AnsiblePilot Home