How to Replace Strings and Lines with Ansible

Ansible provide multiple ways that you can use to replace a string, an entire line or words that match a certain pattern. There are two modules that you can use to achieve this: the replace module and the inline module. We are going to dive deep and take a look at some examples of how these modules can be used in a playbook to replace strings and lines.

Replacing a string from a file with Ansible

The replace module replaces all instances of a defined string within a file.

If the string does not exist, then nothing will be done and no error will be displayed. Ansible simply returns that nothing has been changed. To successfully replace strings in a file, three parameters are required:

  • The location of the file denoted by the ‘path‘ directive.
  • The ‘regexp‘ directive – The string to be replaced or changed. Additionally, you can pass any regular Python expression.
  • The ‘replace‘ directive – This is the replacement word or string.

This is how the syntax looks like with the  replace module:

- replace:
    path: /path/to/file
    regexp: 'string or regular expression for search'
    replace: 'word to replace the search string'
    backup: yes

I have a sample text file called sample.txt which has the content below.

Unix is a free and opensource system used by developers, and desktop lovers.  Thanks to Linux Torvalds’ efforts, Unix grew to become the most popular opensource system.

The goal is to replace the string ‘Unix’ with ‘Linux’. To achieve that, we are going to create a playbook file as shown.

- hosts: 127.0.0.1
  tasks:
  - name: Ansible replace string example
    replace:
      path: /etc/ansible/sample.txt
      regexp: 'Unix'
      replace: "Linux"

We are then going to run the playbook.

# ansible-playbook sample.txt

From the output, you can clearly see that the string ‘Unix’ has been replaced by ‘Linux

Let’s take another example.

Our second objective is to change a hostname entry in my /etc/hosts file from server.myubuntu.com to server.linuxtechi.info

We will create a playbook file change_hostname.yml which will look as follows:

- hosts: 127.0.0.1
  tasks:
  - name: Ansible replace string example
    replace:
      path: /etc/hosts
      regexp:  '(s+)server.myubuntu.com(s+.*)?$'
      replace: '1server.linuxtechi.info2'

Upon running the playbook, the name of the domain name changes accordingly as shown:

# ansible-playbook change_hostname.yml

Ansible lineinfile module

The Ansible inline module can be used in a variety of ways. It can be used for inserting a new line, removing or modifying an existing line from the file. We are going to take a closer look at each of these.

Inserting a line at the end of the file (EOF)

To start off, we will begin by learning how to create a line if it is not present in a file. Begin by specifying the path of the file where you are going to add the line using the path attribute. This has replaced the dest option which was used in Ansible 2.3 and earlier versions.

Then specify the line to be added at EOF. In this case, we’re adding a new entry to the /etc/hosts file. If the line already exists, then Ansible will skip adding it and no changes will be made.

The state parameter instructs Ansible to write the line in the file and the create parameter tells Ansible to create the file if it’s not already there. This is the update_ip.yml playbook  file.

- hosts: 127.0.0.1
  tasks:
    - name: Ansible update IP address
      lineinfile:
        path: /etc/hosts
        line: '173.82.56.150 wwww.linuxtechi.io'
        state: present
        create: yes

When the playbook file is run, notice that the  new entry or line has been added.

# ansible-playbook update_ip.yml

 Inserting a line before or after

Sometimes, you may want to insert a new line just before or after a section of a file and not always at the end of the line. For this, you need to use the insertafter and insertbefore directives.

In the playbook below, we are adding a line to specify our preferred inventory file just after the [defaults] section in the ansible.cfg file. We have escaped the [] since they are regex characters.

- hosts: 127.0.0.1
  tasks:
    - name: Ansible update IP address
      lineinfile:
        path: /etc/ansible/ansible.cfg
        line: 'inventory  = /home/linuxtechi/hosts'
        insertafter: '[defaults]'

To add a line just before a parameter, use the ‘insertbefore‘ parameter. In the example below, we are adding the same line just before the #library pattern in the Ansible config file.

- hosts: 127.0.0.1
  tasks:
    - name: Ansible update IP address
      lineinfile:
        path: /etc/ansible/ansible.cfg
        line: 'inventory  = /home/linuxtechi/hosts'
        insertbefore: ‘#library’

Remove a line using lineinfile module

This is the exact opposite of adding a line. A simple way of achieving this is to set the state parameter to absent . For example, to remove the entry in the file, ensure that the state parameter has the absent value

- hosts: 127.0.0.1
  tasks:
    - name: Ansible update IP address
      lineinfile:
        path: /etc/hosts
        line: ‘173.82.56.150 wwwwlinuxtechi.io’
        state: absent

Another way of removing a line is by using the regexp parameter. For example, the playbook below deletes all lines in a file beginning with the Unix word.

- hosts: 127.0.0.1
  tasks:
    - name: Ansible lineinfile regexp example
      lineinfile:
        dest: /etc.ansible/sample.txt
        regexp: '^Unix'
        state: absent

That’s all from this article, I hope it helps to understand how to replace a string and lines with Ansible.

Also Read: 9 tee Command Examples in Linux