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 Search String in File: lineinfile & regex Guide

By Luca Berton · Published 2024-01-01 · Category: troubleshooting

How to search for strings in files with Ansible. Use lineinfile regex, check mode, shell grep, and slurp module to find and manage text patterns.

Ansible Search String in File: lineinfile & regex Guide

How to Search for a String in a File with Ansible?

I'm going to show you some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.

See also: ansible.builtin.find Module: Search Files by Pattern, Size & Age (Guide)

Ansible module lineinfile

> ansible.builtin.lineinfile: insert, update and remove a single line of text in a file

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.

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 • mode/owner/group - 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/insertbefore. If there is any tool to validate the file we could specify 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 properties.

See also: Ansible Delete File: Remove Files & Directories (state=absent Guide)

Links

ansible.builtin.lineinfile

Playbook

How to Search for a String in a File. How to search for a pattern in a file and return the result using only the Ansible built-in lineinfile module.

code

---
- name: search Playbook
  hosts: all
  vars:
    myfile: "/etc/ssh/sshd_config"
    myline: 'PasswordAuthentication no'
  become: true
  tasks:
    - name: string found
      ansible.builtin.lineinfile:
        name: "{{ myfile }}"
        line: "{{ myline }}"
        state: present
      check_mode: true
      register: conf
      failed_when: (conf is changed) or (conf is failed)

string present

• remote host
$ ssh devops@demo.example.com
[devops@demo ~]$ sudo su
[root@demo devops]# grep 'PasswordAuthentication no' /etc/ssh/sshd_config 
PasswordAuthentication no
[root@demo devops]#
• Ansible execution
$ ansible-playbook -i virtualmachines/demo/inventory file_management/file_search.yml
PLAY [search Playbook] ********************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [string found] *******************************************************************************
ok: [demo.example.com]
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

string different

• remote host
$ ssh devops@demo.example.com
[devops@demo ~]$ sudo su
[root@demo devops]# vim /etc/ssh/sshd_config 
[root@demo devops]# grep 'PasswordAuthentication' /etc/ssh/sshd_config 
PasswordAuthentication yes
[root@demo devops]#
• Ansible execution
$ ansible-playbook -i virtualmachines/demo/inventory file_management/file_search.yml
PLAY [search Playbook] ********************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [string found] *******************************************************************************
fatal: [demo.example.com]: FAILED! => {"backup": "", "changed": true, "failed_when_result": true, "msg": "line added"}
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

file not present

• remote host
$ ssh devops@demo.example.com
[devops@demo ~]$ sudo su
[root@demo ssh]# ls -al /etc/ssh/sshd_config
ls: cannot access '/etc/ssh/sshd_config': No such file or directory
[root@demo ssh]#
• Ansible execution
$ ansible-playbook -i virtualmachines/demo/inventory file_management/file_search.yml
PLAY [search Playbook] ********************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [string found] *******************************************************************************
fatal: [demo.example.com]: FAILED! => {"changed": false, "failed_when_result": true, "msg": "Destination /etc/ssh/sshd_config does not exist !", "rc": 257}
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

code with ❤️ in GitHub

See also: Ansible Check If Directory Exists: stat Module Guide

Conclusion

Now you know how to Search for a String in a File with Ansible and how you could use successfully in your Playbook.

Search and Replace Line

- name: Update config setting
  ansible.builtin.lineinfile:
    path: /etc/myapp/config.conf
    regexp: '^max_connections\s*='
    line: 'max_connections = 200'
  become: true

Check if String Exists

# Using grep
- command: grep -c "error" /var/log/myapp.log
  register: grep_result
  changed_when: false
  failed_when: false

- debug: msg: "Found {{ grep_result.stdout }} errors" when: grep_result.rc == 0

lineinfile Patterns

# Ensure line exists
- lineinfile:
    path: /etc/hosts
    line: "10.0.1.50 db.internal"

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

# Insert after match - lineinfile: path: /etc/fstab insertafter: '^# /data' line: '/dev/sdb1 /data ext4 defaults 0 0'

# Insert before match - lineinfile: path: /etc/nginx/nginx.conf insertbefore: '^}' line: ' include /etc/nginx/conf.d/*.conf;'

# Remove matching line - lineinfile: path: /etc/hosts regexp: 'old-server' state: absent

Regex Search with search Test

- slurp: { src: /etc/myapp/config.yml }
  register: config_raw

- set_fact: config_content: "{{ config_raw.content | b64decode }}"

- debug: msg="Debug mode is enabled!" when: config_content is search('debug:\s*true')

- debug: msg="SSL is configured" when: config_content is search('ssl_cert.*\.pem')

Using find Module

# Find files containing a string
- name: Find configs with old hostname
  command: grep -rl "old-hostname" /etc/
  register: files_with_old
  changed_when: false
  failed_when: false

- name: Replace old hostname replace: path: "{{ item }}" regexp: 'old-hostname' replace: 'new-hostname' loop: "{{ files_with_old.stdout_lines }}" become: true

Replace Module (Multiple Matches)

# Replace ALL occurrences (lineinfile only handles one line)
- ansible.builtin.replace:
    path: /etc/myapp/config.conf
    regexp: 'localhost'
    replace: '10.0.1.50'
  become: true

lineinfile vs replace

| Feature | lineinfile | replace | |---------|-----------|---------| | Scope | Single line | All matches | | Insert | Yes (after/before) | No | | Ensure line | Yes | No | | Multi-line | No | Yes (with (?s)) | | Remove line | Yes (state: absent) | Replaces with empty |

Validate After Change

- lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^Port'
    line: 'Port 2222'
    validate: '/usr/sbin/sshd -t -f %s'
  become: true

FAQ

lineinfile says "changed" but file looks the same?

Check for trailing whitespace differences. Use regexp to match existing line precisely.

How do I handle multi-line blocks?

Use blockinfile for multi-line insertions, or template for complex file management.

Can I search case-insensitively?

regexp: '(?i)^permit_root_login'

Search with lineinfile (check mode)

# Check if a line exists (don't change anything)
- lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    line: 'PermitRootLogin no'
  check_mode: true
  register: result

- debug: msg: "Line {{ 'exists' if not result.changed else 'missing' }}"

Search with grep

- shell: grep -c 'error' /var/log/app.log
  register: error_count
  failed_when: false
  changed_when: false

- debug: msg: "Found {{ error_count.stdout }} errors"

Search with slurp

- slurp:
    src: /etc/myapp/config.yml
  register: config

- set_fact: config_text: "{{ config.content | b64decode }}"

- debug: msg: "Debug mode is enabled" when: "'debug: true' in config_text"

Ensure Line Present

- lineinfile:
    path: /etc/hosts
    regexp: '^10\.0\.1\.10'
    line: '10.0.1.10 db.example.com db'
  become: true

Ensure Line Absent

- lineinfile:
    path: /etc/crontab
    regexp: 'old-backup-job'
    state: absent
  become: true

Replace with Regex

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

Insert After/Before

# Insert after a specific line
- lineinfile:
    path: /etc/myapp/config
    insertafter: '^\[database\]'
    line: 'pool_size = 20'

# Insert before - lineinfile: path: /etc/myapp/config insertbefore: '^\[logging\]' line: 'cache_enabled = true'

Search Multiple Patterns

- shell: "grep -E '(ERROR|CRITICAL|FATAL)' /var/log/app.log | tail -20"
  register: critical_errors
  failed_when: false
  changed_when: false

- debug: msg: "{{ critical_errors.stdout_lines }}" when: critical_errors.stdout_lines | length > 0

replace Module

# Replace all occurrences (not just one line)
- replace:
    path: /etc/myapp/config
    regexp: 'old-hostname\.example\.com'
    replace: 'new-hostname.example.com'
  become: true

blockinfile (Multi-Line)

- blockinfile:
    path: /etc/ssh/sshd_config
    marker: "# {mark} ANSIBLE MANAGED BLOCK"
    block: |
      PermitRootLogin no
      PasswordAuthentication no
      MaxAuthTries 3
  become: true

FAQ

lineinfile vs replace vs blockinfile?

lineinfile — single line operations (ensure present/absent) • replace — regex find/replace across entire file • blockinfile — manage multi-line blocks with markers

How to search without modifying?

Use check_mode: true with lineinfile, or use shell: grep with changed_when: false.

Can I search binary files?

No — use command: strings /path/file | grep pattern for binary files.

Related Articles

skipping tasks with Ansible whenstatic and dynamic Ansible inventorybecome and privilege escalation explaineddesired-state Windows config with Ansible

Category: troubleshooting

Watch the video: Ansible Search String in File: lineinfile & regex Guide — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home