---
title: How to Automate Daily Server Backups with Ansible
siteUrl: https://logzly.com/sysadmininsights
author: sysadmininsights (SysAdmin Insights)
date: 2026-06-19T09:04:23.180760
tags: [ansible, backup, sysadmin]
url: https://logzly.com/sysadmininsights/how-to-automate-daily-server-backups-with-ansible
---


**Disclosure: We are reader supported, and earn affiliate commissions when you buy through us.**


If you’ve ever woken up to a missing database file and a panicked ticket queue, you know why a reliable [backup routine](https://www.amazon.com/s?k=backup+routine&tag=organizationtip101-20) is not a nice‑to‑have, it’s a must‑have. The good news? With Ansible you can set it up once and forget about it—until you need it, of course, just like in our broader [practical guide to automating daily Linux tasks with Ansible](/sysadmininsights/a-practical-guide-to-automating-daily-linux-tasks-with-ansible).

## Why Backups Matter Every Day

A daily backup is the [safety net](https://www.amazon.com/s?k=safety+net&tag=organizationtip101-20) that turns a “whoops” into a quick restore. It protects you from hardware glitches, human error, and the occasional rogue script. For busy sysadmins, the goal is to make the backup process invisible: no manual ssh, no copy‑paste of tar commands, just a reliable playbook that runs while you sip your coffee, similar to the approach we describe for [routine server maintenance with Ansible](/sysadmininsights/automate-routine-server-maintenance-with-ansible-a-practical-30minute-guide-for-sysadmins).

## Prerequisites

Before we dive into the playbook, make sure you have:

* A control node with Ansible installed (any recent 2.9+ version works).
* SSH key‑based access to the target servers.
* A backup destination—could be an NFS share, an S3 bucket, or another server you trust.
* Basic familiarity with Ansible inventory and playbooks.

If any of those sound unfamiliar, pause and get them sorted. Trying to automate without a [solid foundation](https://www.amazon.com/s?k=solid+foundation&tag=organizationtip101-20) is like building a house on sand.

## Step 1 – Define Your Inventory

Create a simple inventory file, `hosts.ini`, that lists the servers you want to [back up](https://www.amazon.com/s?k=back+up&tag=organizationtip101-20).

```
[webservers]
web01.example.com
web02.example.com

[databases]
db01.example.com
```

Group the hosts by role if you need different backup strategies later. Keep the file in a version‑controlled directory so you can track changes.

## Step 2 – Choose What to Back Up

Decide which directories or databases need protection. For this guide we’ll back up:

* `/var/www/html` – website files
* `/etc` – configuration files
* MySQL databases (using `mysqldump`)

You can always add more later; the playbook is modular.

## Step 3 – Write the Backup Playbook

Create a file called `daily_backup.yml`. Below is a stripped‑down version that does the job.

```yaml

- name: Daily server backup
  hosts: all
  become: true
  vars:
    backup_dir: "/tmp/backup_{{ ansible_date_time.iso8601_basic_short }}"
    remote_backup: "backup@example.com:/backups/{{ inventory_hostname }}"
  tasks:

  - name: Ensure backup directory exists
    file:
      path: "{{ backup_dir }}"
      state: directory
      mode: '0755'

  - name: Archive website files
    archive:
      path: /var/www/html
      dest: "{{ backup_dir }}/www_html.tar.gz"
      format: gz

  - name: Archive configuration files
    archive:
      path: /etc
      dest: "{{ backup_dir }}/etc.tar.gz"
      format: gz

  - name: Dump MySQL databases
    mysql_db:
      state: dump
      target: "{{ backup_dir }}/mysql_dump.sql"
      login_user: backup_user
      login_password: "{{ vault_mysql_password }}"
    when: "'databases' in group_names"

  - name: Transfer backup to remote storage
    synchronize:
      src: "{{ backup_dir }}/"
      dest: "{{ remote_backup }}/"
      mode: push
      rsync_opts:
        - "--delete"
    delegate_to: localhost

  - name: Clean up local temp files
    file:
      path: "{{ backup_dir }}"
      state: absent
```

### What the Playbook Does

1. **Creates a temporary folder** on each host with a timestamped name. This keeps each run isolated.
2. **Archives** the website and config directories into gzipped tar files. The `archive` module handles compression for you.
3. **Dumps MySQL** only on hosts that belong to the `databases` group. The `when` clause checks the group membership.
4. **Pushes** the backup files to a remote storage server using `synchronize`, which is a thin wrapper around `rsync`. Running this from the control node avoids opening extra ports on the target.
5. **Deletes** the temporary folder to keep the servers tidy.

## Step 4 – Secure Your Secrets

Never hard‑code passwords. Store them in Ansible Vault and reference them with `{{ vault_mysql_password }}` as shown. Create the vault file with:

```
ansible-vault create vault.yml
```

Add the variable inside, then encrypt it. When you run the playbook, add `--ask-vault-pass` or configure a vault password file.

## Step 5 – Schedule the Playbook

The magic of automation shines when you let cron handle the timing. On your control node, add a cron entry:

```
0 2 * * * /usr/bin/ansible-playbook -i /path/to/hosts.ini /path/to/daily_backup.yml --vault-password-file /path/to/.vault_pass
```

This runs the backup at 2 AM every day—[quiet hours](https://www.amazon.com/s?k=Quiet+Hours&tag=organizationtip101-20) for most environments. Adjust the time to fit your maintenance window.

## Step 6 – Verify and Test

A backup that you never test is just a false sense of security. After the first run:

1. **Check the remote directory** for the expected tar and sql files.
2. **Pick one file** and try to extract it on a test machine.
3. **Restore a small database** from the dump to confirm the `mysqldump` worked.

If anything looks off, tweak the playbook and re‑run. The good thing about Ansible is that it’s idempotent—running the same playbook again won’t break anything.

## Step 7 – Keep an Eye on Logs

Ansible writes a concise report to stdout, but for long‑term tracking you might want to log the output to a file:

```
0 2 * * * /usr/bin/ansible-playbook -i /path/to/hosts.ini /path/to/daily_backup.yml --vault-password-file /path/to/.vault_pass >> /var/log/ansible/backup.log 2>&1
```

Rotate the log with logrotate so it doesn’t grow forever. A quick glance at the log after a week will tell you if any host missed its backup.

## Personal Note: My First Failed Backup

I still remember my first “automated” backup attempt. I wrote a one‑liner shell script, crontabbed it, and went home. The next morning the web server was down because the script had accidentally deleted `/var/www/html`. Lesson learned: let a tool like Ansible handle the file operations, and always test on a non‑production host first. Since then, I’ve never looked back.

## Wrap‑Up

Automating daily backups with Ansible boils down to three things: a clear inventory, a reliable playbook, and a scheduled run. Once you have those pieces in place, you can sleep a little easier knowing your data is safe, and you can spend more time on the fun stuff—like building new services, as we explore in our [practical guide to automating daily Linux tasks with Ansible](/sysadmininsights/a-practical-guide-to-automating-daily-linux-tasks-with-ansible).

Happy automating!
