Ansible replace Module — Regex Find and Replace in Files

What Is ansible.builtin.replace?

The ansible.builtin.replace module performs regex-based find-and-replace operations in files. Unlike lineinfile which works on whole lines, replace can modify parts of a line, handle multiline patterns, and use backreferences — making it ideal for updating configuration values, commenting out blocks, and bulk text transformations.

Parameters Reference

ParameterTypeDefaultDescription
pathstringrequiredFile to modify
regexpstringrequiredPython regex pattern to find
replacestring''Replacement string (supports backreferences)
beforestring—Only replace before this pattern
afterstring—Only replace after this pattern
backupbooleanfalseCreate backup before modifying
encodingstringutf-8File encoding
modestring—File permissions after modification
ownerstring—File owner
groupstring—File group

Basic Usage

---
- name: Replace examples
  hosts: all
  become: true
  tasks:
    - name: Change listen port
      ansible.builtin.replace:
        path: /etc/nginx/nginx.conf
        regexp: 'listen\s+80;'
        replace: 'listen 8080;'

    - name: Update configuration value
      ansible.builtin.replace:
        path: /etc/myapp/config.ini
        regexp: '^(max_connections\s*=\s*)\d+'
        replace: '\g<1>200'

Backreferences

Capture groups let you preserve parts of the matched text:

    - name: Update version preserving prefix
      ansible.builtin.replace:
        path: /opt/app/version.txt
        regexp: '(version=)\d+\.\d+\.\d+'
        replace: '\g<1>3.0.0'

    - name: Swap first and last name
      ansible.builtin.replace:
        path: /etc/myapp/users.txt
        regexp: '(\w+)\s+(\w+)'
        replace: '\2, \1'

Replace Within a Section

Use after and before to limit replacements to a specific section:

    - name: Replace IP only in managed section
      ansible.builtin.replace:
        path: /etc/hosts
        after: '# BEGIN ANSIBLE MANAGED'
        before: '# END ANSIBLE MANAGED'
        regexp: '\d+\.\d+\.\d+\.\d+'
        replace: '192.168.1.100'

Comment Out Lines

    - name: Comment out dangerous options
      ansible.builtin.replace:
        path: /etc/myapp/config.conf
        regexp: '^(dangerous_setting.*)'
        replace: '# \1'
        backup: true

    - name: Uncomment a setting
      ansible.builtin.replace:
        path: /etc/ssh/sshd_config
        regexp: '^#\s*(PermitRootLogin)\s+(.*)'
        replace: '\1 no'

Case-Insensitive Replacement

    - name: Case-insensitive replace
      ansible.builtin.replace:
        path: /etc/myapp/config.ini
        regexp: '(?i)debug\s*=\s*true'
        replace: 'debug = false'

Multiline Patterns

    - name: Remove a multiline block
      ansible.builtin.replace:
        path: /etc/myapp/config.xml
        regexp: '<deprecated>.*?</deprecated>'
        replace: ''

replace vs lineinfile

Featurereplacelineinfile
ScopePart of a lineWhole line
RegexFull Python regexLine matching
Multiple matchesReplaces allOnly last match
BackreferencesYesNo
Insert if missingNoYes
Best forValue updatesLine presence

Troubleshooting

  • Regex not matching — Python regex, not grep/sed; test with python3 -c "import re; print(re.findall(r'pattern', open('file').read()))"
  • Backslash escaping — Double-escape in YAML: \d+ for regex \d+
  • Not idempotent — If replacement text matches the regex, the task runs every time; design patterns to avoid this
  • File not changed — The regexp may not exist in the file; use ansible.builtin.command: grep to verify

Conclusion

The ansible.builtin.replace module handles regex-based text modification with backreferences, section boundaries, and multiline support. Use it when you need to modify specific values within lines rather than replacing entire lines.