Categories
Ansible

Using RSYNC with Ansible

The past week I found myself in a situation where I had to copy a directory to a remote SMB share, using it as a backup destination.

I didn’t had a login to the remote server, just a share and credentials for it, so the easiest way to sync all the data was to use rsync.

After I coded a small bash script to execute rsync, the business requirements changed, and this storage was indented to be used as an “offline” backup. Of course the best way to execute an offline copy is to set up an intermediate host, with the following steps:

  1. Mount a share from the intermediate server
  2. Copy the data to this share
  3. Unmount the share
  4. Mount the share in the destination server
  5. Copy the data from the share
  6. Unmount the share

By using an intermediate server, the source host of the data and the backup destination are never directly connected, meaning that a compromised origin server has no way to directly compromise the destination server, in the worst case scenario.

At the moment the intermediate server is waiting to be deployed, to I had to wrote a quick Ansible playbook to mount the remote share, copy the data, and unmount the share after the copy.

Instead of running rsync for the first copy, I suggest to run a standard copy because there is nothing to compare on the destination, and we will save some time and bandwidth.

An email notification was added to the playbook to get feedback about the synchronization result, as it was syncing about 1TB of data over a slow WAN link.

---
- hosts: remote_server
  gather_facts: no
  become: yes

  tasks:

    - name: Mount external storage
      mount:
        src: //this_is_a_smb_path/on_another_server
        path: /srv/external
        state: mounted
        fstype: cifs
        opts: username=myuser,password=mypass

    - name: Rsync /srv/data to /srv/external
      synchronize:
        archive: yes
        compress: yes
        src: /srv/data
        dest: /srv/external
      delegate_to: remote_server
      register: sync

    - name: Unmount external storage
      mount:
        src: //this_is_a_smb_path/on_another_server
        path: /srv/external
        state: unmounted

    - name: Send e-mail
      mail:
        host: my.smtp.server
        port: 25
        subject: Ansible Backup Report
        body: "Backup status is {{ sync.rc }}"
        from: Ansible Backups <ansible-backup@server.com>
        to:
        - notifications@domain.com