Introduction#
La sauvegarde régulière des configurations réseau est une bonne pratique essentielle. Perdre la configuration d’un switch peut entraîner des heures de reconfiguration manuelle. Dans cet article, nous allons mettre en place une solution complète et automatisée avec Ansible, systemd et un partage réseau Windows, pour sauvegarder les configurations de vos switches localement et à distance.
Prérequis#
- Ansible installé sur le serveur Linux
- SSH activé sur les switches
- Un partage réseau Windows monté (optionnel, pour la sync distante)
- Les collections Ansible nécessaires selon vos équipements :
dellemc.os6
arubanetworks.aoscx
cisco.ios
1. Préparation de l’environnement#
Créer le dossier de destination des sauvegardes :
1
|
mkdir /home/user1/switch_backups
|
2. Inventaire des switches#
Créer un fichier switches.yml listant tous les équipements à sauvegarder :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
switches:
- ip: 192.168.1.10
name: SWITCH01
os: dellemc.os6.os6
password: 1!2$3*4@5678
user: user1
- ip: 192.168.1.20
name: SWITCH02
os: zyxel
password: 1!2$3*4@5678
user: user1
- ip: 192.168.1.30
name: SWITCH03
os: arubanetworks.aoscx.aoscx
password: 1!2$3*4@5678
user: user1
- ip: 192.168.1.40
name: SWITCH04
os: cisco.ios.ios
password: 1!2$3*4@5678
user: user1
|
⚠️ En production, utilisez Ansible Vault pour chiffrer les mots de passe.
3. Le playbook Ansible#
Créer le fichier backup_conf_switches.yml dans votre dossier de projet :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
---
- hosts: localhost
gather_facts: no
vars:
backup_dir: "/home/user1/switch_backups"
backup_day: "{{ lookup('pipe', 'date +%Y%m%d') }}"
backup_time: "{{ lookup('pipe', 'date +%H%M%S') }}"
vars_files:
- switches.yml
tasks:
- name: Créer le répertoire du jour pour la sauvegarde
file:
path: "{{ backup_dir }}/{{ backup_day }}"
state: directory
mode: '0755'
- name: Créer l'inventaire dynamique
add_host:
name: "{{ item.name }}"
groups: switches_to_backup
ansible_host: "{{ item.ip }}"
ansible_network_os: "{{ item.os }}"
ansible_connection: network_cli
ansible_user: "{{ item.user }}"
ansible_password: "{{ item.password }}"
ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
backup_dir: "{{ backup_dir }}"
backup_day: "{{ backup_day }}"
backup_time: "{{ backup_time }}"
loop: "{{ switches }}"
- name: Sauvegarder les configurations des switches
hosts: switches_to_backup
gather_facts: no
vars:
ansible_become: yes
ansible_become_method: enable
tasks:
- name: Récupérer la configuration running
dellemc.os6.os6_command:
commands:
- show running-config
register: switch_config
ignore_errors: yes
- name: Tentative alternative si la première échoue
dellemc.os6.os6_command:
commands:
- show run
register: switch_config_alt
when: switch_config is failed
ignore_errors: yes
- name: Déterminer quelle configuration utiliser
set_fact:
final_config: "{{ switch_config.stdout[0] if switch_config is success
else (switch_config_alt.stdout[0] if switch_config_alt is success else '') }}"
- name: Sauvegarder la configuration sur le disque
copy:
content: "{{ final_config }}"
dest: "{{ backup_dir }}/{{ backup_day }}/{{ inventory_hostname }}_{{ backup_day }}_{{ backup_time }}_config.txt"
delegate_to: localhost
when: final_config | length > 0
- name: Confirmer la sauvegarde
debug:
msg: "✅ {{ inventory_hostname }} sauvegardé"
when: final_config | length > 0
- name: Signaler les erreurs
debug:
msg: "❌ {{ inventory_hostname }}: impossible de récupérer la configuration"
when: final_config | length == 0
- name: Rapport final
hosts: localhost
gather_facts: no
vars:
backup_dir: "/home/user1/switch_backups"
backup_day: "{{ lookup('pipe', 'date +%Y%m%d') }}"
tasks:
- name: Lister les fichiers créés
find:
paths: "{{ backup_dir }}/{{ backup_day }}"
patterns: "*_config.txt"
register: backup_files
- name: Afficher le résumé
debug:
msg:
- "=========================================="
- "📁 Sauvegarde du jour : {{ backup_day }}"
- "✅ Configurations : {{ backup_files.matched }}"
- "📂 Dossier : {{ backup_dir }}/{{ backup_day }}"
- "=========================================="
- name: Créer ou mettre à jour le journal
lineinfile:
path: "{{ backup_dir }}/backup_log.txt"
line: "{{ backup_day }} - {{ backup_files.matched }} switch(es) sauvegardé(s)"
create: yes
mode: '0644'
|
Le playbook fonctionne en trois phases :
- Phase localhost — création du répertoire horodaté et génération de l’inventaire dynamique à partir du fichier
switches.yml
- Phase switches — connexion SSH à chaque équipement, récupération du
running-config avec fallback, et écriture locale du fichier texte
- Phase rapport — comptage des fichiers créés et mise à jour d’un journal de bord
4. Le service systemd#
Créer /etc/systemd/system/backup-switches.service :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# /etc/systemd/system/backup-switches.service
[Unit]
Description=Sauvegarde Ansible des configurations switches
After=network-online.target
[Service]
Type=oneshot
User=admin01
WorkingDirectory=/home/user1/netbox_ansible
ExecStart=/home/admin01/netbox_ansible/venv/bin/ansible-playbook backup_conf_switches.yml -vvv
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
|
Un service Type=oneshot s’exécute une seule fois puis s’arrête — c’est parfaitement adapté à une tâche planifiée. Il ne faut surtout pas l’activer directement avec enable seul, mais l’associer à un timer.
5. Le timer systemd#
C’est le timer qui déclenche le service de façon planifiée. Créer /etc/systemd/system/backup-switches.timer :
1
2
3
4
5
6
7
8
9
10
11
12
|
# /etc/systemd/system/backup-switches.timer
[Unit]
Description=Lancement mensuel du backup des switches
[Timer]
# Déclenchement le 1er de chaque mois à 05h00
OnCalendar=*-*-01 05:00:00
# Rattraper un déclenchement manqué si le serveur était éteint
Persistent=true
[Install]
WantedBy=timers.target
|
Activer et démarrer le timer#
1
2
3
4
5
|
# Recharger la configuration systemd
sudo systemctl daemon-reload
# Activer et démarrer le TIMER (pas le service directement)
sudo systemctl enable --now backup-switches.timer
|
Vérifications utiles#
1
2
3
4
5
6
7
8
|
# Voir quand le prochain déclenchement aura lieu
systemctl list-timers backup-switches.timer
# Consulter les logs d'exécution
journalctl -u backup-switches.service -f
# Tester manuellement le service
sudo systemctl start backup-switches.service
|
6. Synchronisation vers un partage réseau (optionnel)#
Si vous souhaitez synchroniser les sauvegardes vers un partage Windows (SMB), ajoutez un rsync-switches.service et son timer associé, en ciblant le point de montage :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# /etc/systemd/system/rsync-switches.service
[Unit]
Description=Backup local et distant des configurations switches
After=network-online.target
Requires=mnt-windows_share.automount
After=mnt-windows_share.automount
[Service]
Type=oneshot
User=toto
WorkingDirectory=/home/toto/ansible
ExecStart=/bin/bash /home/toto/ansible/backup_wrapper.sh
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
|
Avec son timer pour une exécution toutes les 6 heures :
1
2
3
4
5
6
7
8
9
10
11
12
|
# /etc/systemd/system/rsync-switches.timer
[Unit]
Description=Timer pour sync des configs switches vers partage réseau
[Timer]
OnBootSec=5min
OnUnitActiveSec=6h
Persistent=true
Unit=rsync-switches.service
[Install]
WantedBy=timers.target
|
1
2
|
sudo systemctl daemon-reload
sudo systemctl enable --now rsync-switches.timer
|
Récapitulatif de l’architecture#
| Composant |
Rôle |
switches.yml |
Inventaire des équipements |
backup_conf_switches.yml |
Playbook Ansible de sauvegarde |
backup-switches.service |
Exécute le playbook (oneshot) |
backup-switches.timer |
Planifie l’exécution (1er du mois à 5h) |
rsync-switches.service |
Synchronise vers le partage réseau |
rsync-switches.timer |
Planifie la sync (toutes les 6h) |
Conclusion#
Cette solution combine la puissance d’Ansible pour l’automatisation réseau multi-constructeur avec la fiabilité de systemd pour la planification. Les points forts :
- Multi-constructeur : Dell, Zyxel, Aruba, Cisco supportés nativement
- Résilience : fallback automatique en cas d’échec de commande,
Persistent=true pour rattraper les exécutions manquées
- Traçabilité : journal horodaté, logs systemd consultables avec
journalctl
- Extensible : ajout d’un switch = une ligne dans
switches.yml