Replace Strings and Lines with Ansible Replace Module

The Ansible replace module is designed to handle simple and complex text substitutions in files. It's particularly useful when you need to make consistent changes across multiple systems or files. The module allows you to search for a string or a pattern and replace it with a new value.

Here are some of the key features of Ansible replace module:

  • Idempotency: Ensures the change is made only if necessary.
  • Flexibility: Supports regular expressions for advanced text matching.
  • Simplicity: Easy to use with straightforward parameters.

In this tutorial, we'll explore how to use the Ansible replace module to modify strings and lines in files.

Basic Syntax

Let's look at the basic syntax of the replace module:

- name: Replace a string in a file
  ansible.builtin.replace:
    path: /path/to/file
    regexp: 'old_string'
    replace: 'new_string'

This Ansible playbook search for a specific string, old_string in a file located at /path/to/file and replace it with a new string, \new_string. It uses the replace module from Ansible's built-in library to perform this string replacement. The task ensures that every occurrence of old_string in the specified file is replaced with new_string.

Replacing a Simple String

Suppose you have a configuration file where you need to replace localhost with 127.0.0.1. Here’s how you can achieve this:

Create a playbook with the following content:

---
- name: Replace localhost with 127.0.0.1
  hosts: all
  tasks:
    - name: Replace localhost with 127.0.0.1
      ansible.builtin.replace:
        path: /etc/example.conf
        regexp: 'localhost'
        replace: '127.0.0.1'

Explanation:

  • path: Specifies the file to modify.
  • regexp: The pattern to search for (in this case, localhost).
  • replace: The new value to substitute (127.0.0.1).

Now, run the above playbook.

ansible-playbook replace_string.yml

Ansible will display a summary of changes made. If localhost was found and replaced, it will show that the task has changed.

PLAY [Replace localhost with 127.0.0.1] ****************************************

TASK [Gathering Facts] *********************************************************
ok: [hostname]

TASK [Replace localhost with 127.0.0.1] ****************************************
changed: [hostname]

PLAY RECAP *********************************************************************
hostname                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Changing a Specific Line

Imagine you need to update the port number in a configuration file from 8080 to 9090.

Let's create a playbook and add the following content:

---
- name: Replace port number in configuration file
  hosts: all
  tasks:
    - name: Replace port 8080 with 9090
      ansible.builtin.replace:
        path: /etc/example.conf
        regexp: '^port=8080'
        replace: 'port=9090'

Explanation:

  • regexp: The pattern ^port=8080 ensures we only match lines that start with port=8080.

Now, run the above playbook.

ansible-playbook replace_port.yml

Ansible will update the port number and indicate that the task has changed.

PLAY [Replace port number in configuration file] *******************************

TASK [Gathering Facts] *********************************************************
ok: [hostname]

TASK [Replace port 8080 with 9090] *********************************************
changed: [hostname]

PLAY RECAP *********************************************************************
hostname                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Using Regular Expressions for Advanced Replacements

Suppose you need to replace any occurrence of version 1.0 with version 2.0, regardless of its position in the file.

Create a playbook with the following content:

---
- name: Replace version number using regex
  hosts: all
  tasks:
    - name: Replace version 1.0 with version 2.0
      ansible.builtin.replace:
        path: /etc/example.conf
        regexp: 'version\s+1\.0'
        replace: 'version 2.0'

Explanation:

  • regexp: The pattern version\s+1\.0 matches version 1.0 with any amount of whitespace in between.

Now, run the above playbook.

ansible-playbook replace_version.yml

Ansible will replace all instances of version 1.0 with version 2.0.

PLAY [Replace version number using regex] **************************************

TASK [Gathering Facts] *********************************************************
ok: [hostname]

TASK [Replace version 1.0 with version 2.0] ************************************
changed: [hostname]

PLAY RECAP *********************************************************************
hostname                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Replacing a String with Backup

Sometimes you want to ensure that the original file is preserved before making changes. For example, if the replacement string already exists, you can use the backup parameter to ensure the original file is preserved before changes are made.

- name: Replace with backup
  ansible.builtin.replace:
    path: /etc/example.conf
    regexp: 'old_string'
    replace: 'new_string'
    backup: yes

Now, run the above playbook.

ansible-playbook idempotency_backup.yml

You will see the following output.

PLAY [Replace with backup] *****************************************************

TASK [Gathering Facts] *********************************************************
ok: [hostname]

TASK [Replace old_string with new_string with backup] **************************
changed: [hostname]

PLAY RECAP *********************************************************************
hostname                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Replacing a Multiline Pattern

In some cases, you might need to replace a block of text spanning multiple lines. Here's how you can handle multiline replacements.

Create a playbook with the following content.

- name: Replace a multiline pattern
  hosts: all
  tasks:
    - name: Replace multiline text
      ansible.builtin.replace:
        path: /etc/example.conf
        regexp: 'START_PATTERN.*?END_PATTERN'
        replace: 'NEW_PATTERN'
        backup: yes

Explanation:

  • regexp: The pattern START_PATTERN.*?END_PATTERN matches any text between START_PATTERN and END_PATTERN.
  • replace: Substitutes the matched text with NEW_PATTERN.

Now, run this playbook.

ansible-playbook replace_multiline.yml

You will see the following output.

PLAY [Replace a multiline pattern] *********************************************

TASK [Gathering Facts] *********************************************************
ok: [hostname]

TASK [Replace multiline text] **************************************************
changed: [hostname]

PLAY RECAP *********************************************************************
hostname                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Case-Insensitive Replacement

If you need to perform a case-insensitive replacement, you can use the ignorecase parameter.

Let's create a playbook.

- name: Case-insensitive replacement
  hosts: all
  tasks:
    - name: Replace case-insensitive text
      ansible.builtin.replace:
        path: /etc/example.conf
        regexp: 'caseInsensitivePattern'
        replace: 'newPattern'
        backup: yes
        ignorecase: yes

Explanation:

  • ignorecase: This parameter makes the replacement case-insensitive.

Now, run the above playbook.

ansible-playbook replace_case_insensitive.yml

You will see the following output.

PLAY [Case-insensitive replacement] ********************************************

TASK [Gathering Facts] *********************************************************
ok: [hostname]

TASK [Replace case-insensitive text] *******************************************
changed: [hostname]

PLAY RECAP *********************************************************************
hostname                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Conclusion

In this article, we explored the Ansible replace module and its practical applications. We covered how to replace simple strings, change specific lines, use regular expressions for advanced text manipulations, create backups, handle multiline patterns, and perform case-insensitive replacements.

If you are new to Ansible and want to learn it from scratch, our Ansible tutorial series will be of great help. It's written for RHCE exam but it helps you the same whether you are preparing for the exam or not.

RHCE Ansible EX294 Exam Preparation Course
Learn all the essentials of Ansible with this hands-on tutorial series. It is ideal for RHCE Ansible EX294 exam preparation.
✍️
Author: Hitesh Jethwa has more than 15+ years of experience with Linux system administration and DevOps. He likes to explain complicated topics in easy to understand way.