coopdevs.backups_role
rol_backup
Estrategias de copia de seguridad y restauración para proyectos de Coopdevs.
Requisitos
Este rol utiliza Restic con la ayuda de restic-ansible.
Variables del rol
# Versión de Restic
rol_backup_version_restic: '0.16.4'
# Ubicación de los scripts
rol_backup_ruta: '/opt/backup'
rol_backup_directorio_scripts: "{{ rol_backup_ruta }}/bin"
# Nombre modificable de la plantilla para generar
#+ el script "prepare", que será incrustado dentro
#+ del script renderizado `rol_backup_ruta_script`
rol_backup_template_script_prepare: "cron-prepare.sh.j2"
# Si modificas rol_backup_template_script_prepare, significa que no estás usando
#+ la plantilla de script por defecto y por lo tanto no necesitamos crear roles de postgres, etc.
#+ y puede que no necesites permisos de sudo para tar. Por lo tanto, deshabilitamos
#+ las tareas relacionadas por defecto. Sin embargo, si deseas habilitar esas tareas,
#+ establece en verdadero las variables correspondientes:
rol_backup_postgresql_habilitado:
rol_backup_sudoers_habilitado:
# Ruta completa al script renderizado formado por main, prepare y upload.
rol_backup_ruta_script: "{{ rol_backup_directorio_scripts }}/backup.sh"
# Ubicación de los archivos generados por trabajos cron
rol_backup_ruta_tmp: '/tmp/backups'
# Listas de rutas a hacer copia de seguridad
rol_backup_rutas_activos: []
# Usuario del sistema, su grupo principal y otros adicionales.
#+ Quien ejecutará scripts, restic y trabajos cron
#+ y será el dueño de los directorios y archivos
rol_backup_nombre_usuario: 'backups'
rol_backup_grupo_usuario: 'backups'
rol_backup_grupos_usuario: ''
# Rol interno de solo lectura de PostgreSQL para realizar el volcado
rol_backup_nombre_usuario_postgresql: "{{ rol_backup_nombre_usuario }}"
# Rol de administrador interno de Postgres
usuario_postgresql: "postgres"
rol_backup_nombres_db: [ "postgres" ]
# Nombre del repositorio de Restic utilizado solo en caso
#+ de que necesitemos dirigirse a diferentes repositorios restic
rol_backup_nombre_repositorio_restic: {{ escaped_inventory_hostname }}
#########################################
### ¡ADVERTENCIA! Variables sensibles abajo ###
#########################################
### Considera colocarlas dentro de un ###
### ansible-vault. Como ejemplo, consulta ###
### defaults/secrets.yml.example ###
#########################################
# Contraseña para el usuario de copias de seguridad no privilegiado de postgresql
rol_backup_contraseña_usuario_postgresql:
# Contraseña del repositorio de Restic. Una nueva contraseña que proporcionas para cifrar las copias.
rol_backup_contraseña_repositorio_restic:
# URL del bucket remoto en formato restic
# Ejemplo para backblaze: "b2:nombrebucket:ruta/al/repo". Es probable que
# "b2:nombrebucket:/" funcione para ti.
# Ejemplo para repositorio local: "/var/backups/repo"
rol_backup_url_repositorio_restic:
# Clave "de aplicación" de Backblaze, restringida al bucket mencionado arriba
# Más sobre esto en el archivo de ejemplo de secretos y
# en https://gitlab.com/coopdevs/b2-bucket-and-key
rol_backup_b2_clave_id_aplicacion:
rol_backup_b2_clave_aplicacion:
Dependencias
Uso
Necesitarás preparar un inventario para tus hosts con las variables anteriores. Por ejemplo, en inventory/hosts
.
Ejemplo de playbook de PostgreSQL con copias de seguridad
# playbooks/main.yml
---
- name: Instalar PostgreSQL con copias de seguridad automáticas
hosts: servidores
become: yes
roles:
- role: geerlingguy.postgresql
- role: coopdevs.rol_backup
Playbook para restaurar una copia de seguridad en el controlador
# playbooks/restore.yml
---
- name: Restaurar copia de seguridad localmente
hosts: servidores
connection: local
tasks:
- import_role:
name: coopdevs.rol_backup
tasks_from: restore-to-controller.yml
Playbook para restaurar una copia de seguridad en el host
# playbooks/restore-in-situ.yml
---
- name: Restaurar copia de seguridad en el host
hosts: servidores
tasks:
- import_role:
name: coopdevs.rol_backup
tasks_from: restore-to-host.yml
Restaurar instantánea usando el playbook de arriba
ansible-playbook playbooks/restore.yml -i inventory/hosts -l servidores
Este playbook no instalará ningún binario globalmente, pero aún necesita privilegios de root. Por lo tanto, es posible que necesites proporcionar la contraseña de sudo:
ansible-playbook playbooks/restore.yml -i inventory/hosts -l servidores --ask-become-pass
Por defecto, crea un directorio con restic y un envoltorio útil y restaura la última instantánea. Finalmente, elimina de forma segura el envoltorio, ya que contiene credenciales que no queremos que queden expuestas. Sin embargo, si prefieres instalar el envoltorio y usarlo manualmente, puedes ejecutar el playbook con la etiqueta install
:
ansible-playbook playbooks/restore.yml -i inventory/hosts -l servidores --tags install
Script de copia de seguridad personalizada
Cuando tu aplicación no utiliza PostgreSQL o el script de copia de seguridad no se ajusta a tus necesidades, puedes proporcionar el tuyo pasando una nueva plantilla a rol_backup_template_script_prepare
. Puedes usar los mismos métodos auxiliares log
y run
especificados en cron-main.sh.j2. Puedes referirte a cualquier variable que hayas especificado en la declaración de include_role
.
La carga de la copia de seguridad en el almacenamiento de objetos no se puede personalizar, así que aún necesitas especificar las rutas donde tu script deja los archivos de copia de seguridad con rol_backup_rutas_activos
. Sí, esa variable debería llamarse algo como rol_backup_archivo_a_subir
o similar. Consulta cron-upload.sh.j2 para más detalles.
Ten en cuenta que, aunque no se aplica en este caso, esta variable también se usa en cron-prepare.sh para listar los archivos a respaldar y esto puede ser muy confuso. Tiene dos usos diferentes.
Consulta https://github.com/coopdevs/donalo/pull/82 o https://gitlab.com/coopdevs/odoo-provisioning/-/tree/master/roles/backups para ejemplos listos para producción.
Variables sensibles
Por favor, protege al menos las variables que están debajo de "variables sensibles" mencionadas arriba. Para ello, utiliza Ansible Vault para cifrar con una frase de contraseña el archivo de configuración con estas variables.
Backblaze
Backblaze proporciona dos tipos de claves: cuenta o maestra, y aplicación. Solo hay una clave de cuenta y tiene poder sobre todas las demás claves y todos los buckets. Podemos tener muchas claves de aplicación, que pueden tener acceso de lectura y escritura a todos o exactamente un bucket.
No debemos usar la clave de cuenta para acceder a un bucket ni reutilizar las claves de aplicación. Incluso si las contraseñas de restic son diferentes y los buckets son diferentes, un servidor podría eliminar las copias de seguridad de otros, o incluso crear más buckets, llenarlos y aumentar la factura.
Por lo tanto, usamos claves de aplicación en lugar de la clave maestra. Según ansible-restic
, solo pasa las credenciales a restic, independiente del tipo de clave. En realidad, configuramos la clave_de_cuenta_b2
de ansible-restic
(que sugiere usar la clave maestra) con la rol_backup_b2_clave_aplicacion
(que sugiere usar una clave de aplicación).
Lo que restic llama "Clave de cuenta" aparece en la web de B2 como "Clave de aplicación maestra".
Si deseas crear un nuevo bucket y una clave de aplicación restringida, puedes usar el script Backblaze bucket and key.
Restic
Restic creará un "repositorio" durante la provisión de Ansible. Esto parece un directorio dentro del bucket de BackBlaze siendo la ruta dentro del bucket la última parte de rol_backup_url_repositorio
, separada por :
. Si deseas colocarlo en la raíz, prueba algo como b2:mibucket:/
. Más sobre esto en la documentación de restic. Desde fuera, verás:config data index keys locks snapshots
Y si lo descifras, por ejemplo, al montarlo:hosts ids snapshots tags
Sin embargo, probablemente quieras restaurar solo una instantánea particular del repositorio. Para hacerlo, usa restic restore
. Necesitarás proporcionarle el id de la instantánea que deseas restaurar y el directorio de destino donde descargarlo. Puedes explorar instantáneas haciendo restic snapshots
. Un caso particular es restaurar la última instantánea, donde puedes usar latest
como id de instantánea.
Para restaurar solo un archivo de la última instantánea en lugar de todo el repositorio, puedes usar el subcomando dump
: restic dump latest myfile > /home/user/myfile
.
Recuerda que todos los comandos de restic necesitan saber dónde comunicarse y con qué credenciales. Por lo que puedes pasarlas como parámetros o exportarlas como variables de entorno. Para este caso, necesitamos:
export RESTIC_REPOSITORY="b2:nombre_de_mibucket:/"
export RESTIC_PASSWORD="frase larga con al menos 7 palabras"
export B2_ACCOUNT_ID="nuestra clave de aplicación id"
export B2_ACCOUNT_KEY="nuestra clave de aplicación que es muy larga y tiene números y letras mayúsculas"
Licencia
GPLv3
ansible-galaxy install coopdevs.backups_role