Sauvegarder et restaurer la configuration d'un routeur

1. Théorie

Sauvegarder la configuration d’un routeur

---
- name: BACKUP ROUTER CONFIGURATIONS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: BACKUP THE CONFIG
      ios_config:
        backup: yes
      register: config_output

Le paramètre backup du module ios_config déclenche la sauvegarde de la configuration et l’enregistre dans le dossier local backup/.

Nettoyer la configuration sauvegardée

La configuration rapratriée commencera par deux lignes qui doivent être enlevées :

Building configuration...

Current configuration with default configurations exposed : 393416 bytes

Le module lineinfile est celui qui permet de manipuler les lignes de texte des fichiers à la manière de sed.

Nettoyage d’une correspondance exacte sur une ligne

    - name: REMOVE NON CONFIG LINES
      lineinfile:
        path: "./backup/{{inventory_hostname}}.config"
        line: "Building configuration..."
        state: absent

Utiliser motif d’expression rationnelle (RegExp)

    - name: REMOVE NON CONFIG LINES - REGEXP
      lineinfile:
        path: "./backup/{{inventory_hostname}}.config"
        regexp: 'Current configuration.*'
        state: absent

Restaurer une configuration

Pour restaurer une configuration, nous pouvons adopter l’approche suivante :

  • Copier la configuration nettoyée sur les périphériques.
  • Utiliser les commandes du fabricant pour restaurer la configuration.

Dans cet exemple, nous utilisons la commande Cisco config replace qui permet d’appliquer seulement la différence entre la configuration courante (“running-config”) et la configuration copiée.

---
- name: RESTORE CONFIGURATION
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: COPY RUNNING CONFIG TO ROUTER
      command: scp ./backup/{{inventory_hostname}}.config {{inventory_hostname}}:/{{inventory_hostname}}.config

    - name: CONFIG REPLACE
      ios_command:
        commands:
          - config replace flash:{{inventory_hostname}}.config force

Notez l’utilisation de la variable “inventory_hostname” qui désigne le nom du périphérique dans l’inventaire.

Lab a - Sauvegarder la configuration du routeur

Dans ce scénario réaliste, il est proposé de créer un livre de jeu qui sauvegarde la configuration des routeurs Cisco. Dans l’exercice qui suit celui-ci, on utilisera cette sauvegarde pour un exercice de restauration.

Étape 1

Veuillez créer un nouveau fichier nommé backup.yml en utilisant votre éditeur de texte préféré avec la définition du jeu qui suit :

---
- name: BACKUP ROUTER CONFIGURATIONS
  hosts: cisco
  connection: network_cli
  gather_facts: no

Le livre de jeu s’applique aux périphériques du groupe “cisco” de l’inventaire.

Étape 2

Veuillez créer une nouvelle tâche qui utilise le module ios_config avec le paramètre backup: yes qui créera une dossier backup/ avec la configuration de chaque routeur.

Note : La commande ansible-doc ios_config ou le site docs.ansible.com vous aidera dans la compréhension du module.

---
- name: BACKUP ROUTER CONFIGURATIONS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: BACKUP THE CONFIG
      ios_config:
        backup: yes
      register: config_output

Pourquoi capturer la sortie de cette tâche dans une variable appelée config_output? L’Étape 5 du lab vous donnera la réponse.

Étape 3

Veuillez exécuter ce livre de jeu.

ansible-playbook backup.yml
PLAY [BACKUP ROUTER CONFIGURATIONS] *********************************************************************************************************************************************************

TASK [BACKUP THE CONFIG] ********************************************************************************************************************************************************************
ok: [rtr1]
ok: [rtr3]
ok: [rtr4]
ok: [rtr2]

PLAY RECAP **********************************************************************************************************************************************************************************
rtr1                       : ok=1    changed=0    unreachable=0    failed=0
rtr2                       : ok=1    changed=0    unreachable=0    failed=0
rtr3                       : ok=1    changed=0    unreachable=0    failed=0
rtr4                       : ok=1    changed=0    unreachable=0    failed=0

Étape 4

Ce livre de jeu devrait créer un dossier nommé “backup”. Voyons ce qu’il contient :

ls -l backup
total 1544
-rw-rw-r--. 1 student1 student1 393514 Jun 19 12:45 rtr1_config.2018-06-19@12:45:36
-rw-rw-r--. 1 student1 student1 393513 Jun 19 12:45 rtr2_config.2018-06-19@12:45:38
-rw-rw-r--. 1 student1 student1 390584 Jun 19 12:45 rtr3_config.2018-06-19@12:45:37
-rw-rw-r--. 1 student1 student1 390586 Jun 19 12:45 rtr4_config.2018-06-19@12:45:37

Il est recommandé de vérifier le contenu de ces fichiers avec un pager comme less.

Étape 5

La configuration sauvegardée devient désormais une source pour la restaurer.

Tentons de renommer ce fichier pour refléter le nom du périphérique.

Dans l’Étape 2, vous avez capturé la sortie de la tâche dans une variable nommée config_output. Cette variable contient le nom du fichier sauvegardé.

Nous allons utiliser le module copy pour remplir cet objectif.

---
- name: BACKUP ROUTER CONFIGURATIONS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: BACKUP THE CONFIG
      ios_config:
        backup: yes
      register: config_output

    - name: RENAME BACKUP
      copy:
        src: "{{config_output.backup_path}}"
        dest: "./backup/{{inventory_hostname}}.config"

Étape 6

Veuillez exécuter à nouveau le livre de jeu.

ansible-playbook backup.yml
PLAY [BACKUP ROUTER CONFIGURATIONS] *********************************************************************************************************************************************************

TASK [BACKUP THE CONFIG] ********************************************************************************************************************************************************************
ok: [rtr3]
ok: [rtr4]
ok: [rtr2]
ok: [rtr1]

TASK [RENAME BACKUP] ************************************************************************************************************************************************************************
changed: [rtr1]
changed: [rtr4]
changed: [rtr2]
changed: [rtr3]

PLAY RECAP **********************************************************************************************************************************************************************************
rtr1                       : ok=2    changed=1    unreachable=0    failed=0
rtr2                       : ok=2    changed=1    unreachable=0    failed=0
rtr3                       : ok=2    changed=1    unreachable=0    failed=0
rtr4                       : ok=2    changed=1    unreachable=0    failed=0

Étape 7

De nouveau, nous trouvons nos sauvegardes dans le dossier backup/.

ls -l backup
total 3088
-rw-rw-r--. 1 student1 student1 393514 Jun 19 13:35 rtr1.config
-rw-rw-r--. 1 student1 student1 393514 Jun 19 13:35 rtr1_config.2018-06-19@13:35:14
-rw-rw-r--. 1 student1 student1 393513 Jun 19 13:35 rtr2.config
-rw-rw-r--. 1 student1 student1 393513 Jun 19 13:35 rtr2_config.2018-06-19@13:35:13
-rw-rw-r--. 1 student1 student1 390584 Jun 19 13:35 rtr3.config
-rw-rw-r--. 1 student1 student1 390584 Jun 19 13:35 rtr3_config.2018-06-19@13:35:12
-rw-rw-r--. 1 student1 student1 390586 Jun 19 13:35 rtr4.config
-rw-rw-r--. 1 student1 student1 390586 Jun 19 13:35 rtr4_config.2018-06-19@13:35:13

Notez qu’on y trouve les premières sauvegardes à côté des nouvelles.

Étape 8

Si nous tentons de restaurer manuellement la configuration, nous obtiendrons une erreur qui tient aux deux premières lignes du fichier :

Building configuration...

Current configuration with default configurations exposed : 393416 bytes

Il est nécessaire de “nettoyer” la configuration de ces deux lignes pour être en mesure de la restaurer.

Veuillez écrire une nouvelle tâche avec le module lineinfile qui aura pour objectif de retirer la première ligne.

---
- name: BACKUP ROUTER CONFIGURATIONS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: BACKUP THE CONFIG
      ios_config:
        backup: yes
      register: config_output

    - name: RENAME BACKUP
      copy:
        src: "{{config_output.backup_path}}"
        dest: "./backup/{{inventory_hostname}}.config"

    - name: REMOVE NON CONFIG LINES
      lineinfile:
        path: "./backup/{{inventory_hostname}}.config"
        line: "Building configuration..."
        state: absent

Note: L’argument line: demande une correspondance exacte, ici avec l’occurence “Building configuration…”.

Étape 9

Avant de lancer le livre de jeu, nous avons besoin d’ajouter une ou plusieurs tâches pour enlever la seconde ligne “Current configuration …etc”. Etant donné que l’occurence à trouver est variable sur le nombre d’octets : “… bytes”, on utilisera le paramètres regexp du module lineinfile pour désigner un motif de ce type.

---
- name: BACKUP ROUTER CONFIGURATIONS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: BACKUP THE CONFIG
      ios_config:
        backup: yes
      register: config_output

    - name: RENAME BACKUP
      copy:
        src: "{{config_output.backup_path}}"
        dest: "./backup/{{inventory_hostname}}.config"

    - name: REMOVE NON CONFIG LINES
      lineinfile:
        path: "./backup/{{inventory_hostname}}.config"
        line: "Building configuration..."
        state: absent

    - name: REMOVE NON CONFIG LINES - REGEXP
      lineinfile:
        path: "./backup/{{inventory_hostname}}.config"
        regexp: 'Current configuration.*'
        state: absent

Étape 10

Veuillez exécuter le livre de jeu.

ansible-playbook backup.yml
PLAY [BACKUP ROUTER CONFIGURATIONS] *********************************************************************************************************************************************************

TASK [BACKUP THE CONFIG] ********************************************************************************************************************************************************************
ok: [rtr2]
ok: [rtr4]
ok: [rtr1]
ok: [rtr3]

TASK [RENAME BACKUP] ************************************************************************************************************************************************************************
changed: [rtr2]
changed: [rtr4]
changed: [rtr3]
changed: [rtr1]

TASK [REMOVE NON CONFIG LINES] **************************************************************************************************************************************************************
changed: [rtr4]
changed: [rtr1]
changed: [rtr2]
changed: [rtr3]

TASK [REMOVE NON CONFIG LINES - REGEXP] *****************************************************************************************************************************************************
changed: [rtr1]
changed: [rtr3]
changed: [rtr2]
changed: [rtr4]

PLAY RECAP **********************************************************************************************************************************************************************************
rtr1                       : ok=4    changed=3    unreachable=0    failed=0
rtr2                       : ok=4    changed=3    unreachable=0    failed=0
rtr3                       : ok=4    changed=3    unreachable=0    failed=0
rtr4                       : ok=4    changed=3    unreachable=0    failed=0

Étape 11

Si vous affichez les premières du fichier, vous constaterez que les deux lignes indésirables ne sont plus présentes.

head -n 10 backup/rtr1.config

!
! Last configuration change at 14:25:42 UTC Tue Jun 19 2018 by ec2-user
!
version 16.8
downward-compatible-config 16.8
no service log backtrace
no service config
no service exec-callback
no service nagle

Note: La commande Unix head affiche les N premières lignes d’un fichier en argument.

Lab b - Utiliser Ansible pour restaurer la configuration sauvegardée

Dans le lab précédent, vous avez appris à sauvegarder la configuration des quatre routeurs Cisco. Dans ce lab, vous apprendrez à restaurer un fichier de configuration qui a été placé dans le dossier backup/.

backup
├── rtr1.config
├── rtr1_config.2018-06-07@20:36:05
├── rtr2.config
├── rtr2_config.2018-06-07@20:36:07
├── rtr3.config
├── rtr3_config.2018-06-07@20:36:04
├── rtr4.config
└── rtr4_config.2018-06-07@20:36:06

Notre objectif est de restaurer la dernière configuration correcte connue sur les routeurs.

Étape 1

Sur l’un de ces routeurs, par exemple rtr1, nous allons réaliser quelques changements manuels comme par exemple la création d’une interface de Loopback.

Veuillez vous connecter sur rtr1 et exécuter les commandes suivantes :

rtr1#config terminal
Enter configuration commands, one per line.  End with CNTL/Z.
rtr1(config)#interface loopback 101
rtr1(config-if)#ip address 169.1.1.1 255.255.255.255
rtr1(config-if)#end
rtr1#

Maintenant, veuillez vérifier votre configuration :

rtr1#sh run interface loopback 101
Building configuration...

Current configuration : 67 bytes
!
interface Loopback101
 ip address 169.1.1.1 255.255.255.255
end

rtr1#

Étape 2

L’Étape 1 simule un changement “hors bande/hors processus” sur le réseau. Ce changement a besoin d’être corrigé. Nous allons donc écrire un nouveau livre de jeu qui applique la sauvegarde enregistrée précédemment.

Veuillez créer un fichier restore_config.yml en définissant le jeu suivant :

---
- name: RESTORE CONFIGURATION
  hosts: cisco
  connection: network_cli
  gather_facts: no

Étape 3

Il s’agit maintenant de créer une tâche qui copiera la configuration sur le routeur en SSH/SCP par exemple.

---
- name: RESTORE CONFIGURATION
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: COPY RUNNING CONFIG TO ROUTER
      command: scp ./backup/{{inventory_hostname}}.config  {{inventory_hostname}}:/{{inventory_hostname}}.config

Note: On utilise la variable inventory_hostname qui reprend le nom d’inventaire de la cible. Le module command utilise la ligne de commande comme argument avec le binaire scp et la destination bootflash: ou flash: du périphérique Cisco (CSR ou IOSv).

Étape 4

Veuillez exécuter le livre de jeu.

ansible-playbook restore_config.yml
PLAY [RESTORE CONFIGURATION] *********************************************************

TASK [COPY RUNNING CONFIG TO ROUTER] *************************************************
changed: [rtr1]
changed: [rtr2]
changed: [rtr3]
changed: [rtr4]

PLAY RECAP ***************************************************************************
rtr1                       : ok=1    changed=1    unreachable=0    failed=0
rtr2                       : ok=1    changed=1    unreachable=0    failed=0
rtr3                       : ok=1    changed=1    unreachable=0    failed=0
rtr4                       : ok=1    changed=1    unreachable=0    failed=0

Étape 5

Veuillez vous connecter sur vos routeurs et vérifier la présence du fichier avec la commande dir :

ssh rtr1
rtr1#dir
Directory of bootflash:/

   11  drwx            16384  May 11 2018 21:30:28 +00:00  lost+found
   12  -rw-        380928984  May 11 2018 21:32:05 +00:00  csr1000v-mono-universalk9.16.08.01a.SPA.pkg
   13  -rw-         38305434  May 11 2018 21:32:06 +00:00  csr1000v-rpboot.16.08.01a.SPA.pkg
   14  -rw-             1967  May 11 2018 21:32:06 +00:00  packages.conf
235713  drwx             4096   Jun 4 2018 18:08:56 +00:00  .installer
186945  drwx             4096   Jun 4 2018 18:08:44 +00:00  core
   15  -rw-               58   Jun 4 2018 18:08:30 +00:00  iid_check.log
113793  drwx             4096   Jun 4 2018 18:08:32 +00:00  .prst_sync
73153  drwx             4096   Jun 4 2018 18:08:44 +00:00  .rollback_timer
81281  drwx             4096   Jun 7 2018 22:03:48 +00:00  tracelogs
227585  drwx             4096   Jun 4 2018 18:16:10 +00:00  .dbpersist
130049  drwx             4096   Jun 4 2018 18:09:41 +00:00  virtual-instance
   16  -rw-               30   Jun 4 2018 18:11:05 +00:00  throughput_monitor_params
   17  -rw-            10742   Jun 4 2018 18:16:08 +00:00  cvac.log
   18  -rw-               16   Jun 4 2018 18:11:14 +00:00  ovf-env.xml.md5
   19  -rw-               16   Jun 4 2018 18:11:14 +00:00  .cvac_skip_once
   20  -rw-              209   Jun 4 2018 18:11:15 +00:00  csrlxc-cfg.log
170689  drwx             4096   Jun 4 2018 18:11:16 +00:00  onep
373889  drwx             4096   Jun 8 2018 00:41:04 +00:00  syslog
   21  -rw-               34   Jun 4 2018 18:16:15 +00:00  pnp-tech-time
   22  -rw-            50509   Jun 4 2018 18:16:16 +00:00  pnp-tech-discovery-summary
341377  drwx             4096   Jun 4 2018 18:16:21 +00:00  iox
   23  -rw-           394307   Jun 8 2018 01:26:51 +00:00  rtr1.config

7897378816 bytes total (7073292288 bytes free)
rtr1#

Étape 6

Maintenant que la configuration correcte est placée sur la cible, ajoutons une nouvelle tâche qui remplacera la configuration courante (“running-config”) avec celle que nous avons placée.

---
- name: RESTORE CONFIGURATION
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: COPY RUNNING CONFIG TO ROUTER
      command: scp ./backup/{{inventory_hostname}}.config {{inventory_hostname}}:/{{inventory_hostname}}.config

    - name: CONFIG REPLACE
      ios_command:
        commands:
          - config replace flash:{{inventory_hostname}}.config force

Note : Dans cet exemple, nous avons pris avantage de la fonctionnalité archive de Cisco. La commande config replace mettra à jour uniquement les différences et non l’entièreté des commandes.

Étape 7

Veuillez lancer le livre de jeu nouvellement adapté.

ansible-playbook restore_config.yml
PLAY [RESTORE CONFIGURATION] *********************************************************

TASK [COPY RUNNING CONFIG TO ROUTER] *************************************************
changed: [rtr1]
changed: [rtr3]
changed: [rtr2]
changed: [rtr4]

TASK [CONFIG REPLACE] ****************************************************************
ok: [rtr1]
ok: [rtr2]
ok: [rtr4]
ok: [rtr3]

PLAY RECAP ***************************************************************************
rtr1                       : ok=2    changed=1    unreachable=0    failed=0
rtr2                       : ok=2    changed=1    unreachable=0    failed=0
rtr3                       : ok=2    changed=1    unreachable=0    failed=0
rtr4                       : ok=2    changed=1    unreachable=0    failed=0

Étape 8

Enfin, vous pouvez valider le fait que l’interface ajoutée dans l’Étape 1 n’est plus présente sur le périphérique.

ssh rtr1
rtr1#sh ip int br
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       172.16.165.205  YES DHCP   up                    up
Loopback0              192.168.1.101   YES manual up                    up
Loopback1              10.1.1.101      YES manual up                    up
Tunnel0                10.100.100.1    YES manual up                    up
Tunnel1                10.200.200.1    YES manual up                    up
VirtualPortGroup0      192.168.35.101  YES TFTP   up                    up
rtr1#sh run inter
rtr1#sh run interface Loo
rtr1#sh run interface Loopback 101
                               ^
% Invalid input detected at '^' marker.

rtr1#

Vous avez réussi à sauvegarder et à restaurer la configuration de vos routeurs Cisco !

Licence

License MIT github.com/network-automation/linklight