Automatización de backups diarios de bases de datos MySQL con Ansible
Si gestionas varios servidores MySQL, sabes que los backups regulares no solo son recomendables, son vitales.
Hoy traigo un playbook Ansible que automatiza completamente la generación y almacenamiento ordenado de copias de seguridad de todas tus bases de datos MySQL.
Este ejemplo, de dificultad intermedia, permite ejecutar copias diarias, personalizar horarios, y emparejarlo fácilmente con políticas de retención.
¿Por qué automatizar backups de bases de datos con Ansible?
- Consistencia. No volverás a olvidar un backup ni depender de tareas manuales o scripts desperdigados.
- Control centralizado. Gestiona desde un punto común todos los servidores con una sola orden.
- Fácil integración. Puedes hacer que los backups formen parte de flujos de CI/CD, o combinarlos con otras tareas Ansible (actualizaciones, hardening, rotación de logs, etc).
- Recuperación rápida ante imprevistos. Disponer de copias frescas y ordenadas por fecha lo cambia todo el día que se rompe algo.
Código completo del playbook
Este playbook realiza, para todos los hosts definidos como mysql_servers
, los siguientes pasos:
- Instalar
mysqldump
si es necesario. - Crear el directorio de backups local en el servidor, añadiendo la fecha al nombre (ejemplo:
/var/backups/mysql/2025-07-30/
). - Descubrir automáticamente todas las bases de datos y, salvo las de sistema (
information_schema
,mysql
, …), sacar su volcado conmysqldump
. - Almacenar todos los backups individualmente, uno por base de datos, comprimidos con
gzip
. - (Opcional: puedes añadir pasos de rotación/eliminación de backups antiguos según tus políticas).
Repositorio ansible_mysql_backup.yml
---
- name: Backup programado de todas las bases de datos MySQL
hosts: mysql_servers
become: true
vars:
backup_dir: "/var/backups/mysql/{{ ansible_date_time.date }}"
mysql_user: "backup_user"
mysql_password: "mi_password_backup"
exclude_dbs:
- information_schema
- mysql
- performance_schema
- sys
tasks:
- name: Instalar cliente MySQL si falta
apt:
name: mysql-client
state: present
- name: Crear directorio de backups con fecha
file:
path: "{{ backup_dir }}"
state: directory
mode: '0750'
- name: Obtener lista de bases de datos
mysql_db:
login_user: "{{ mysql_user }}"
login_password: "{{ mysql_password }}"
state: list
register: dbs
- name: Definir lista de bases a copiar (sin bases de sistema)
set_fact:
user_databases: "{{ dbs.databases | difference(exclude_dbs) }}"
- name: Dump de cada base de datos en archivos comprimidos
loop: "{{ user_databases }}"
vars:
db_name: "{{ item }}"
shell: |
mysqldump -u {{ mysql_user }} -p'{{ mysql_password }}' {{ db_name }} | gzip > "{{ backup_dir }}/{{ db_name }}.sql.gz"
args:
creates: "{{ backup_dir }}/{{ db_name }}.sql.gz"
environment:
MYSQL_PWD: "{{ mysql_password }}"
- name: (Opcional) Rotar/eliminar backups antiguos (más de 7 días)
find:
paths: /var/backups/mysql
age: 7d
age_stamp: mtime
recurse: yes
patterns: "*.gz"
register: old_backups
- name: (Opcional) Borrar dumps antiguos
file:
path: "{{ item.path }}"
state: absent
with_items: "{{ old_backups.files }}"
when: old_backups.matched > 0
¿Cómo uso este playbook?
- Asegúrate de tener creado el usuario
backup_user
con privilegios de sólo lectura en MySQL. - Consulta tus
hosts
oinventory
y pon todos tus servidores MySQL en el grupomysql_servers
. - Puedes programar la ejecución diaria con
cron
en el servidor donde ejecutas Ansible, apuntando alansible-playbook
. - Personaliza la variable
backup_dir
o la retención de backups si lo deseas.
Consejos finales y troubleshooting rápido
- ¿Error de permisos para escribir en
/var/backups/mysql
? Usabecome: true
y revisa la configuración de sudo. - Protege las credenciales: puedes usar Ansible Vault para cifrar el archivo que contiene
mysql_password
. - ¿Tu servidor tiene muchos datos? Comprime los dumps en tiempo real, como en el ejemplo, para ocupar mucho menos.
- Revisión de logs: si algo falla, repasa el output de
ansible-playbook
para saber en qué base de datos ha saltado el error.
Automatizar los backups no sustituye revisar si realmente se están generando y restauran bien. Haz pruebas de restauración periódicas.