Replace a String in a File with Ansible Replace Module

Ansible Replace Module

The replace module in Ansible is used to search for a specified pattern in a file and replace it with a given string. This is particularly useful for making changes to configuration files, scripts, or any text-based file on remote hosts.

In this guide, we’ll explore the Ansible replace module in depth with several practical examples to demonstrate its versatility.

Basic Usage

To use the replace module, you define a task in your playbook specifying the file path, the pattern to search for, and the replacement string. Here’s a basic example:

- name: Replace a string in a file
  ansible.builtin.replace:
    path: /etc/myconfig.conf
    regexp: 'old_value'
    replace: 'new_value'
    backup: yes

This task searches for the string old_value in the file /etc/myconfig.conf and replaces it with new_value.

Here is a brief explanation of each parameter.

  • path: The path to the file to be modified.
  • regexp: The regular expression to search for within the file.
  • replace: The replacement string.
  • backup: Whether to create a backup of the file before making changes.
  • validate: A validation command to run before making any changes.

Example 1: Updating Configuration Settings

Let’s say you have a configuration file /etc/myapp/config.ini with a setting that needs to be updated:

[database]
host = localhost
port = 3306

You want to change the host value to dbserver.example.com. Here’s how you can do it with the playbook:

- name: Update database host in configuration file
  hosts: all
  become: yes
  tasks:
    - name: Update database host in configuration file
      ansible.builtin.replace:
        path: /etc/myapp/config.ini
        regexp: '^host = .*'
        replace: 'host = dbserver.example.com'

Example 2: Backing Up Files Before Replacement

It’s often a good practice to create a backup of a file before making changes. The replace module supports this with the backup option:

Here is an example playbook for backing up a file before replacement.

- name: Update configuration with backup
  hosts: all
  become: yes
  tasks:
    - name: Update configuration with backup
      ansible.builtin.replace:
        path: /etc/myapp/config.ini
        regexp: '^host = .*'
        replace: 'host = dbserver.example.com'
        backup: yes

This playbook replaces any line in /etc/myapp/config.ini that starts with host = with host = dbserver.example.com, and backs up the original file before making the change.

Example 3: Conditional Replacement Based on Validation

You can perform a replacement only if a certain condition is met by using the validate parameter. This is useful when you need to ensure that the file maintains a certain state after modification.

Suppose you want to update the server_name in an Nginx configuration file only if the file is valid after the change:

- name: Update server name in Nginx config
  hosts: all
  become: yes
  tasks:
    - name: Update server name in Nginx config
      ansible.builtin.replace:
        path: /etc/nginx/sites-available/default
        regexp: 'server_name .*;'
        replace: 'server_name newsite.example.com;'
        backup: yes
        validate: 'nginx -t -c %s'

This task will replace server_name with newsite.example.com and validate the Nginx configuration before applying the changes.

Example 4: Using Regular Expressions with Capture Groups

Regular expressions with capture groups can be used to retain parts of the original text while making replacements. This is particularly useful when you need to change only a portion of a matched pattern.

Suppose you have a file with entries like this:

user1 = oldpassword123
user2 = oldpassword456

And you want to update the passwords but keep the usernames:

- name: Update user passwords in config file
  hosts: all
  become: yes
  tasks:
    - name: Update user passwords in config file
      ansible.builtin.replace:
        path: /etc/users.conf
        regexp: '^(user[0-9]+ = )oldpassword[0-9]+$'
        replace: '\1newpassword789'

This playbook updates the /etc/users.conf file by replacing passwords in lines that start with user followed by a number and oldpassword with newpassword789, preserving the user prefix and number.

Example 5: Replacing Multiple Lines Using Multi-line Mode

Sometimes you need to replace or update multiple lines of text. The replace module supports multi-line replacement using the regexp parameter.

Assume you have a block of configuration that needs to be updated:

- name: Replace a multi-line block in a configuration file
  hosts: all
  become: yes
  tasks:
    - name: Replace a multi-line block in a configuration file
      ansible.builtin.replace:
        path: /etc/myapp/config.conf
        regexp: |
          section {
            option1 = value1
            option2 = value2
          }
        replace: |
          section {
            option1 = newvalue1
            option2 = newvalue2
          }

This task will replace the entire block matching the multi-line pattern.

Example 6: Replacing Text in Multiple Files

You can use the replace module in combination with the find module to replace text in multiple files. This is useful when you need to make the same change across several files in a directory.

- name: Replace text in multiple files
  hosts: all
  become: yes
  tasks:
    - name: Find all .conf files in a directory
      ansible.builtin.find:
        paths: /etc/myapp/
        patterns: '*.conf'
      register: conf_files

    - name: Replace text in all found .conf files
      ansible.builtin.replace:
        path: "{{ item.path }}"
        regexp: 'oldsetting'
        replace: 'newsetting'
      loop: "{{ conf_files.files }}"

This playbook uses the find module to find all .conf files in the specified directory and then uses the loop to apply the replacement to each file.

Example 7: Replacing Regular Expressions

In some cases, you may need to perform replacements based on more complex patterns using regular expressions (regex). The replace module supports regex, allowing you to specify sophisticated patterns for matching and replacing content.

Suppose you have a configuration file where URLs need to be updated, and the old URLs follow a pattern of http://example.com/resource/*. The new URLs should follow the pattern https://newdomain.com/resource/*. The wildcard * represents any subpath.

Here’s how you can use the replace module to update these URLs using regex:

- name: Replace old URLs with new URLs using regex
  hosts: all
  become: yes
  tasks:
    - name: Replace old URLs with new URLs using regex
      ansible.builtin.replace:
        path: /etc/app/config.conf
        regexp: 'http://example\.com/resource/(.*)'
        replace: 'https://newdomain.com/resource/\1'

In this example:

  • regexp: The regex pattern http://example\.com/resource/(.*) matches the old URLs. The \. escapes the dot, and (.*) captures the subpath.
  • replace: The https://newdomain.com/resource/\1 replaces the matched pattern, where \1 refers to the captured subpath from the regex.

Example 8: Replacing with Case Insensitivity

Sometimes, the text you want to replace may vary in case. The replace module allows for case-insensitive replacements using the ignorecase parameter. This is useful when you want to ensure that all variations of a word or phrase, regardless of case, are replaced.

Suppose you have a document where the word “Server” needs to be standardized to “server” throughout the document, regardless of how it is capitalized (e.g., “Server,” “server,” “SERVER”).

Here’s how to replace all variations of “Server” with “server”:

- name: Replace all variations of 'Server' with 'server'
  hosts: all
  become: yes
  tasks:
    - name: Replace all variations of 'Server' with 'server'
      ansible.builtin.replace:
        path: /etc/app/document.txt
        regexp: 'Server'
        replace: 'server'
        ignorecase: yes

In this example:

  • regexp: The pattern Server is matched in a case-insensitive manner.
  • replace: All matched instances are replaced with the lowercase server.
  • ignorecase: This parameter is set to yes to ignore case during the search and replace.

This task ensures that all instances of the word “Server” are standardized to “server,” regardless of their original casing in the file.

Conclusion

The replace module in Ansible is a versatile tool for modifying file contents on remote systems. By understanding its parameters and capabilities, you can perform a wide range of text replacements in your automation tasks.

About Hitesh Jethva

I am Hitesh Jethva, Founder and Author at Code2DevOps.com. With over 15 years of experience in DevOps and open source technologies, I am passionate about empowering teams through automation, continuous integration, and scalable solutions.

View all posts by Hitesh Jethva