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 Replace • Ansible blockinfile Module: Manage Text Blocks • Ansible template Module: Deploy Configuration FilesCategory: database-automation