How to find and replace text/IP address with Ansible

Posted on in Categories , last updated September 21, 2017

I need to find an IP address in the sshd_config file and replace with a fresh one for over 100+ VMs. How do I use Ansible to do so? Is it possible to search replace single string or IP address?

Yes, you can use the following Ansible modules:

  • replace – This module will replace all instances of a pattern within a file.
  • lineinfile – Same as replace but this is primarily useful when you want to change a single line in a file only.

How to find and replace text/IP address with Ansible

How do I replace all instances of a pattern within a file?

The syntax is as follows:

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

For example, find and replace all instances of foo with bar within a file named /etc/app.conf by creating or updating your yml file:

- replace:
    path: /etc/app.conf
    regexp: 'foo'
    replace: 'bar'
    backup: yes

Another example to replace hostname server1.cyberciti.biz with server1.nixcraft.com in /etc/hosts:

- replace:
    path: /etc/hosts
    regexp: '(\s+)server1\.cyberciti\.biz(\s+.*)?$'
    replace: '\1server1.nixcraft.com\2'
    backup: yes

In this example, replace an IP address 202.51.1.1 with 203.55.5.5 in sshd_config and reload sshd service:

# sshd.yml
          - replace:
                  dest: /etc/ssh/sshd_config
                  regexp: '202.51.1.1'
                  replace: '203.55.5.5'
                  backup: yes
                  validate: '/usr/sbin/sshd -t'
          - service:
                  name: sshd
                  state: reloaded

You can run it as follows:
$ ansible-playbook -i hosts sshd.yml

Example for lineinfile module

Update ip address in /etc/hosts file:

# my.yml
- lineinfile:
    path: /etc/hosts
    regexp: '^202\.51\.1\.1'
    line: '202.55.5.5 www.cyberciti.biz'
    owner: root
    group: root
    mode: 0644
    backup: yes

Update sshd_config:

# my.yml
- lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^202\.51\.1\.1'
    line: 'Match Address 202.55.5.5'
    backup: yes
    validate: '/usr/sbin/sshd -t'
- service:
    name: sshd
    state: reloaded

Update/create your hosts file:

$ cat hosts
[cluster:vars]
ansible_user=vivek 
ansible_become=true
ansible_become_method=sudo

[cluster]
vm1
vm2
vm3
vm4
gc.vm1
gc.vm2
gc.vm3
gc.vm4
aws.vm1
aws.vm2
aws.vm3
aws.vm4

You can run it as follows:
$ ansible-playbook -i hosts my.yml

References:
  1. replace – Replace all instances of a particular string in a file using a back-referenced regular expression.
  2. lineinfile – Ensure a particular line is in a file, or replace an existing line using a back-referenced regular expression.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

Leave a Comment