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+.

Share this on (or read 4 comments/add one below):

4 comment

  1. You seem to be using some RegEx in your examples that is not clear to people who are not experienced with RegEx. Can you explain what the syntax is actually doing?

    I.E. (\s+) does what, exactly? Is it looking for server1.cyberciti.biz or Server1.cyberciti.biz ?

Leave a Comment