Set-OPS-Public/roles/client_backup/defaults/main.yml

92 lines
4.2 KiB
YAML
Raw Normal View History

---
# Sauvegarde applicative (logique) d'un nœud vers la cible restic hors-nœud.
# Chaque nœud déclare ses "jobs" ; restic chiffre côté client + applique la rétention.
client_backup_paquets:
- restic
# Cible (nœud serveur_backup) + transport SSH.
client_backup_cible: "backup-01.{{ domaine_interne }}"
client_backup_utilisateur_distant: "restic"
client_backup_ssh_key: "/etc/setops/backup_ed25519"
# Dépôt restic (un sous-dossier par nœud, relatif au home de l'utilisateur distant).
client_backup_repo: "sftp:{{ client_backup_utilisateur_distant }}@{{ client_backup_cible }}:{{ inventory_hostname }}"
client_backup_password: "{{ vault_restic_password | default('') }}"
client_backup_ssh_privkey: "{{ vault_backup_ssh_privkey | default('') }}"
# Dossier de préparation des dumps (pg_dump, slapcat, forgejo dump...).
client_backup_staging: "/var/backups/setops"
# Rétention (restic forget).
client_backup_retention: "--keep-daily 7 --keep-weekly 4 --keep-monthly 6"
# Planification (timer systemd).
client_backup_horaire: "*-*-* 02:30:00"
# Jobs déclaratifs. Chaque job :
# nom : identifiant
# commande : (optionnel) dump écrivant dans {{ staging }}/{{ nom }}
# chemins : liste de chemins à inclure dans le snapshot restic
#
# CATALOGUE PAR GROUPE — c'est le rôle qui POSSEDE la donnée qui dit comment la sortir.
# On sauvegarde l'ETAT NON REGENERABLE, pas ce que le code reconstruit : ni les zones
# PowerDNS ni les tableaux de bord Grafana ne figurent ici, ils se redéploient.
#
# Les chemins reprennent les defauts du role proprietaire, mais NE PEUVENT PAS y faire
# reference : `make deployer` deroule un play par groupe, et les defaults de
# `serveur_forgejo` ne sont pas charges pendant le play de `client_backup`. D'ou la forme
# `var | default(litteral)` — la variable gagne si l'inventaire la definit, sinon le
# defaut du role proprietaire, recopie ici et a garder aligne avec lui.
client_backup_catalogue:
serveur_step_ca:
nom: step_ca
chemins:
- "{{ serveur_step_ca_steppath | default('/etc/step-ca') }}"
serveur_openldap:
nom: openldap
# slapcat lit la base a plat : pas d'authentification, coherent meme slapd arrete.
commande: >-
slapcat -b '{{ serveur_openldap_base_dn | default("dc=" + domaine_interne.split(".") | join(",dc=")) }}'
> {{ client_backup_staging }}/openldap/annuaire.ldif
chemins: ["{{ client_backup_staging }}/openldap"]
serveur_postgresql:
nom: postgresql
# pg_dumpall : TOUTES les bases + les roles et leurs mots de passe. Une base oubliee
# ici serait une base perdue — d'ou le dump global plutot qu'une liste a maintenir.
commande: >-
runuser -u postgres -- pg_dumpall --clean
> {{ client_backup_staging }}/postgresql/toutes-bases.sql
chemins: ["{{ client_backup_staging }}/postgresql"]
serveur_dovecot:
nom: courriel
chemins: ["{{ serveur_dovecot_vmail_base | default('/var/vmail') }}"]
serveur_forgejo:
nom: forgejo
chemins:
- "{{ serveur_forgejo_data | default('/var/lib/forgejo') }}"
- "{{ serveur_forgejo_config_dir | default('/etc/forgejo') }}"
serveur_nextcloud:
nom: nextcloud
chemins:
- "{{ serveur_nextcloud_data_dir | default('/var/www/nextcloud/data') }}"
- "{{ (serveur_nextcloud_racine | default('/var/www/nextcloud')) + '/config' }}"
serveur_rspamd:
# Le bayes APPRIS est de l'etat : reconstruire le noeud reinstalle rspamd, pas ce
# qu'il a appris. Les regles, elles, se redeploient et ne sont pas ici.
nom: rspamd
chemins: ["/var/lib/rspamd"]
serveur_web_frontal:
nom: web_frontal
chemins: ["{{ serveur_web_frontal_racine_base | default('/srv/web') }}"]
serveur_web_dorsal:
nom: web_dorsal
chemins: ["{{ serveur_web_dorsal_racine | default('/srv/webapp') }}"]
# Jeux retenus pour CE noeud : intersection du catalogue et de ses groupes. Derive, donc
# un tenant qui deplace un service emporte sa sauvegarde avec lui, sans rien re-declarer.
client_backup_jobs: >-
{{ client_backup_catalogue | dict2items
| selectattr('key', 'in', group_names) | map(attribute='value') | list }}
supervision : c'est le DEPOT qui dit ou en sont les sauvegardes Icinga ne surveillait rien : aucun objet Host ni Service de Set-OPS, seulement la config Debian d'origine sur localhost. Superviser setops-sauvegarde.service aurait reproduit le defaut du jour meme : l'unite etait VERTE sur onze noeuds pendant qu'elle n'emportait rien. Le noeud sait qu'il a LANCE sa sauvegarde, pas qu'elle est ARRIVEE. backup-01 evalue donc ses depots et pousse un resultat passif par noeud vers l'API Icinga. Trois criteres, parce qu'un seul suffit a mentir : l'instantane existe, il est recent (26 h / 50 h), il contient au moins un fichier. Le sens du flux est delibere : le depot parle a la supervision, jamais l'inverse — compromettre mon-01 ne donne aucun acces aux sauvegardes. Le ttl de 6 h fait la fraicheur : si le rapporteur se tait, Icinga perime les services tout seul. C'est le silence qui a laisse le defaut vivre un mois. Deux erreurs corrigees par la mesure : - --data-urlencode refuse en Bad Request (l'API veut du JSON) ; le flux, le TLS et l'auth marchaient, seule la charge etait perdue. - le seuil « vide » en octets signalait a tort idm-01 (2363 o) : un export LDIF d'un annuaire a un compte pese cela. « Vide » se mesure en FICHIERS. Et le verdict est un AVERTISSEMENT : la machine ne distingue pas « les donnees ont disparu » de « il n'y en a pas encore ». Reserve assumee : curl -k — l'API presente le cert de sa propre AC, pas step-ca. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 21:39:05 -04:00
# La liste EN CLAIR des memes groupes vit dans `vars/main.yml` — sans Jinja, pour que la
# supervision et P36 puissent la lire par `include_vars` sans rendre ce catalogue.