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: Edit Single Lines in Config Files

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

How to edit single lines in files with Ansible lineinfile module. Add, modify, remove lines using regex, manage config files idempotently with examples.

Ansible lineinfile Module: Edit Single Lines in Config Files

Today we're going to talk about how to edit a single-line text in a file with Ansible. Ansible module lineinfile. I'm Luca Berton and welcome to today's episode of Ansible Pilot

Ansible module lineinfile

Today we're talking about the Ansible module lineinfile. The full name is ansible.builtin.lineinfile, which means that is part of the collection of modules "builtin" with ansible and shipped with it. It's a module pretty stable and out for years and it supports a large variety of operating systems. You are able to insert, update and remove a single line of text in a file.

Main Parameters

• path _string_ - file path • line _string_ - text • insertafter/insertbefore _string_ - EOF/regular expression • validate _string_ - validation command • create _boolean_ - create if not exist • state _string_ - present/absent • owner/group/mode - permission • setype/seuser/selevel - SELinux

This module has some parameters to perform any tasks. The only required is "path", where you specify the filesystem path of the file you're going to edit. "line" is the line of text we would like to insert in the file, easy! By default, the text is going to be inserted at the end of the file, but we could personalize it in a specific position with "insertafter" or "insertbefore". If there is any tool to validate the file we could specify it in the validate parameter, very useful for configuration files. If the file does not exist we could also "create" it! Usually, we would like to insert a text line but we could also remove using state in conjunction with parameter absent. Let me also highlight that we could also specify some permissions or SELinux property.

See also: Edit single-line text - Ansible Playbook for Changing IP Address of Remote Hosts

Links

ansible.builtin.lineinfile

Playbook

Are you ready to make your hands dirty? Let's jump in a live Playbook of lineinfile module usage in the Ansible playbook. • lineinfile.yml
---
- name: lineinfile module demo
  hosts: all
  become: true
  tasks:
    - name: allow password authentication
      ansible.builtin.lineinfile:
        state: present
        dest: /etc/ssh/sshd_config
        regexp: "^PasswordAuthentication"
        line: "PasswordAuthentication yes"
        validate: 'sshd -t -f %s'

code with ❤️ in GitHub

See also: Ansible blockinfile Module: Insert & Manage Multi-Line Text Blocks (Guide)

Conclusion

Now you know better the Ansible module lineinfile and you could use it successfully in your playbook.

Common lineinfile Patterns

Add or update a line

- name: Set timezone in config
  ansible.builtin.lineinfile:
    path: /etc/myapp/config.ini
    regexp: '^timezone='
    line: 'timezone=UTC'
  become: true

Add line if not present

- name: Add DNS server
  ansible.builtin.lineinfile:
    path: /etc/resolv.conf
    line: 'nameserver 8.8.8.8'
    state: present
  become: true

Remove a line

- name: Remove old DNS entry
  ansible.builtin.lineinfile:
    path: /etc/resolv.conf
    regexp: '^nameserver 10\.0\.0\.1'
    state: absent
  become: true

Insert after a specific line

- name: Add config after section header
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    insertafter: '^#Port 22'
    line: 'Port 2222'
  become: true
  notify: restart sshd

Insert before a specific line

- name: Add comment before setting
  ansible.builtin.lineinfile:
    path: /etc/myapp/config.ini
    insertbefore: '^max_connections='
    line: '# Maximum database connections (default: 100)'
  become: true

Uncomment a line

- name: Enable password authentication
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?PasswordAuthentication'
    line: 'PasswordAuthentication yes'
  become: true

Modify with backreferences

- name: Double the max connections value
  ansible.builtin.lineinfile:
    path: /etc/myapp/config.ini
    regexp: '^(max_connections=)(\d+)'
    line: '\g<1>200'
    backrefs: true
  become: true

See also: Add Secondary Groups to Linux Users with Ansible Playbook

Validate Before Applying

- name: Update sshd_config safely
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    line: 'PermitRootLogin no'
    validate: '/usr/sbin/sshd -t -f %s'
  become: true

lineinfile vs blockinfile vs replace

| Module | Use Case | |--------|----------| | lineinfile | Add/modify/remove a single line | | blockinfile | Add/modify a block of multiple lines | | replace | Regex find-and-replace (no line constraint) | | template | Generate entire file from Jinja2 template | | copy | Write entire file content |

Key Parameters

| Parameter | Description | |-----------|-------------| | path | Target file | | line | Line content to add/set | | regexp | Regex to find existing line | | state | present (default) or absent | | insertafter | Regex - insert after this line | | insertbefore | Regex - insert before this line | | backrefs | Use regex groups in replacement | | create | Create file if missing | | validate | Command to validate before saving | | backup | Create backup before modifying |

FAQ

Why does lineinfile add duplicate lines?

If regexp doesn't match any existing line, lineinfile appends the line. Use a regex that matches the line you want to modify, including any previous value.

How do I edit multiple lines?

Use blockinfile for a block, or multiple lineinfile tasks. For complex multi-line edits, consider template.

Can I use variables in regexp?

Yes, but escape regex special characters:

regexp: "^{{ item.key | regex_escape }}="
line: "{{ item.key }}={{ item.value }}"

Add a Line

- ansible.builtin.lineinfile:
    path: /etc/hosts
    line: "10.0.1.10 web1.internal"
  become: true

Replace a Line (Regex)

- lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?PermitRootLogin'
    line: 'PermitRootLogin no'
  become: true
  notify: restart sshd

Remove a Line

- lineinfile:
    path: /etc/hosts
    regexp: 'old-server\.internal'
    state: absent
  become: true

Ensure Line After Pattern

- lineinfile:
    path: /etc/myapp/config.conf
    insertafter: '^\[database\]'
    line: 'host = db.production.internal'
  become: true

Ensure Line Before Pattern

- lineinfile:
    path: /etc/nginx/nginx.conf
    insertbefore: '^}'
    line: '    include /etc/nginx/conf.d/*.conf;'
  become: true

Multiple Lines (Loop)

- lineinfile:
    path: /etc/sysctl.conf
    regexp: "^{{ item.key }}"
    line: "{{ item.key }} = {{ item.value }}"
  loop:
    - { key: net.ipv4.ip_forward, value: 1 }
    - { key: vm.swappiness, value: 10 }
    - { key: fs.file-max, value: 65536 }
  become: true
  notify: reload sysctl

Backup Before Change

- lineinfile:
    path: /etc/fstab
    regexp: '^/dev/sdb1'
    line: '/dev/sdb1 /data ext4 defaults 0 2'
    backup: true  # Creates timestamped backup
  become: true

Validate After Change

- lineinfile:
    path: /etc/sudoers
    regexp: '^deploy'
    line: 'deploy ALL=(ALL) NOPASSWD: ALL'
    validate: 'visudo -cf %s'
  become: true

Create File If Missing

- lineinfile:
    path: /etc/myapp/custom.conf
    line: 'setting = value'
    create: true
    mode: '0644'
  become: true

Common Use Cases

# Disable SELinux
- lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: 'SELINUX=disabled'

# Set timezone - lineinfile: path: /etc/timezone regexp: '.*' line: 'America/New_York'

# Comment out a line - lineinfile: path: /etc/myapp/config regexp: '^(dangerous_setting.*)' line: '#\1' backrefs: true

# Uncomment a line - lineinfile: path: /etc/myapp/config regexp: '^#(wanted_setting.*)' line: '\1' backrefs: true

lineinfile vs blockinfile vs template

| Module | Use Case | |--------|----------| | lineinfile | Single line add/replace/remove | | blockinfile | Multi-line block with markers | | template | Full file management | | replace | Regex replace (no line management) |

Key Parameters

| Parameter | Description | |-----------|-------------| | path | Target file | | line | Line to ensure present | | regexp | Pattern to match for replacement | | state | present or absent | | insertafter | Add after matching line | | insertbefore | Add before matching line | | backrefs | Use regex groups in line | | create | Create file if missing | | backup | Backup before change | | validate | Validate command | | firstmatch | Only affect first match |

FAQ

Why does lineinfile add duplicate lines?

If regexp doesn't match any existing line, lineinfile adds the line as new. Use regexp that matches what you're replacing.

How do I use regex groups (backrefs)?

- lineinfile:
    path: /etc/config
    regexp: '^(Port)\s+\d+'
    line: '\1 8080'
    backrefs: true
# Changes "Port 22" to "Port 8080"

Can I replace multiple occurrences?

lineinfile only replaces the last match by default. Use firstmatch: true for the first. For all occurrences, use the replace module.

Set a Config Value

- ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?PermitRootLogin'
    line: 'PermitRootLogin no'
  become: true
  notify: restart sshd

Add a Line

- lineinfile:
    path: /etc/hosts
    line: '10.0.1.10 app.example.com'
  become: true

Remove a Line

- lineinfile:
    path: /etc/hosts
    regexp: '^10\.0\.1\.10'
    state: absent
  become: true

Insert After/Before

# After a pattern
- lineinfile:
    path: /etc/myapp/config.conf
    insertafter: '^\[database\]'
    line: 'host = db.example.com'
  become: true

# Before a pattern - lineinfile: path: /etc/myapp/config.conf insertbefore: '^\[logging\]' line: 'cache_enabled = true' become: true

Multiple Lines

- lineinfile:
    path: /etc/sysctl.conf
    regexp: "^{{ item.key }}"
    line: "{{ item.key }} = {{ item.value }}"
  loop:
    - { key: 'net.ipv4.ip_forward', value: '1' }
    - { key: 'net.ipv4.tcp_syncookies', value: '1' }
    - { key: 'vm.swappiness', value: '10' }
  become: true
  notify: reload sysctl

Backup Before Edit

- lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^PasswordAuthentication'
    line: 'PasswordAuthentication no'
    backup: true
  become: true

Create File If Missing

- lineinfile:
    path: /etc/myapp/custom.conf
    line: 'setting = value'
    create: true
    mode: '0644'
  become: true

Validate After Edit

- lineinfile:
    path: /etc/sudoers
    regexp: '^deploy'
    line: 'deploy ALL=(ALL) NOPASSWD: ALL'
    validate: 'visudo -cf %s'
  become: true

lineinfile vs replace vs blockinfile

| Module | Scope | Use Case | |--------|-------|----------| | lineinfile | Single line | Config key=value | | replace | Regex match | Multi-line regex replace | | blockinfile | Text block | Multi-line sections |

FAQ

regexp but line not found?

If regexp matches nothing, the line is appended to end of file. Use insertafter/insertbefore to control placement.

How to ensure a line is NOT present?

- lineinfile:
    path: /etc/config
    regexp: 'dangerous_setting'
    state: absent

Why does lineinfile keep adding duplicate lines?

Your regexp doesn't match the line you're adding. Ensure regexp would match the exact line text.

Related Articles

Ansible privilege escalation patternsrole-based playbook organization in Ansible

See also

Ansible Rolling Update Debian/Ubuntu: apt Module Guide (Examples)

Category: database-automation

Watch the video: Ansible lineinfile Module: Edit Single Lines in Config Files — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home