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.

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

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

ModuleUse Case
lineinfileAdd/modify/remove a single line
blockinfileAdd/modify a block of multiple lines
replaceRegex find-and-replace (no line constraint)
templateGenerate entire file from Jinja2 template
copyWrite entire file content

Key Parameters

ParameterDescription
pathTarget file
lineLine content to add/set
regexpRegex to find existing line
statepresent (default) or absent
insertafterRegex - insert after this line
insertbeforeRegex - insert before this line
backrefsUse regex groups in replacement
createCreate file if missing
validateCommand to validate before saving
backupCreate 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

ModuleUse Case
lineinfileSingle line add/replace/remove
blockinfileMulti-line block with markers
templateFull file management
replaceRegex replace (no line management)

Key Parameters

ParameterDescription
pathTarget file
lineLine to ensure present
regexpPattern to match for replacement
statepresent or absent
insertafterAdd after matching line
insertbeforeAdd before matching line
backrefsUse regex groups in line
createCreate file if missing
backupBackup before change
validateValidate command
firstmatchOnly 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

ModuleScopeUse Case
lineinfileSingle lineConfig key=value
replaceRegex matchMulti-line regex replace
blockinfileText blockMulti-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.

See also

Category: database-automation

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

Browse all Ansible tutorials · AnsiblePilot Home