NetDevOps
GitOps

De l'intent au BGP Established - Partie 2 : reproduire le lab pas à pas

Mise en œuvre technique du pipeline IBN : deploy.sh, webhook receiver (HMAC, debounce), deploy job en 5 phases (backup, push, NRFU, rollback, circuit breaker), template Jinja2 + GraphQL.

A
Audric VERNET
12 avril 2026
5 min
17

Image non disponible

URL: /blog-assets/ibn-lab/03_clab_topologie_avec_leaf3.png

De l'intent au BGP Established - Partie 2 : reproduire le lab pas à pas

Dans la première partie, nous avons vu le pipeline IBN en action : d'un Proposed Change dans Infrahub à un BGP Established sur leaf3, en passant par le rollback automatique et la protection contre le drift. Cet article détaille la mise en œuvre technique - comment reproduire le lab, comment chaque composant fonctionne, et ce qui se passe sous le capot.

Le code complet est disponible en open source. Toutes les commandes ci-dessous supposent un terminal WSL2 (Ubuntu) sur Windows 11, mais s'adaptent à toute distribution Linux.

Code du lab

Déploiement du lab

Le script deploy.sh installe la stack complète en 7 étapes :

  1. Vérification des prérequis (K3S, Helm, Docker, ContainerLab, kubectl, git, image cEOS)
  2. Ajout des dépôts Helm (Gitea, ArgoCD ; Infrahub est distribué en OCI)
  3. Installation de Gitea + création et initialisation des repos
  4. Installation d'ArgoCD + création de l'Application + webhook receiver
  5. Installation d'Infrahub (chart OCI, version 4.20.0 fixée)
  6. Déploiement de la topologie ContainerLab (2 spines + 2 leafs)
  7. Affichage des URLs et credentials

Les versions Helm sont fixées pour la reproductibilité : Gitea 12.5.0, ArgoCD 9.4.17, Infrahub 4.20.0.

chmod +x deploy.sh && ./deploy.sh

Le setup Infrahub (schéma + données) est séparé :

sudo apt install -y python3-yaml && python3 setup_infrahub.py

Ce script est idempotent - il peut être relancé sans effet de bord.


Le webhook receiver - Bridge Infrahub → Gitea

Le webhook receiver est le pont entre Infrahub (source de vérité) et Gitea (vecteur de déploiement). C'est un serveur HTTP Python (stdlib uniquement) déployé comme Deployment K8s.

Vérification HMAC

Chaque webhook Infrahub est signé avec un shared secret (HMAC-SHA256). Le receiver vérifie la signature avant de traiter l'événement :

  • Headers : webhook-id, webhook-timestamp, webhook-signature
  • Signature : HMAC-SHA256(shared_key, "{id}.{timestamp}.{body}") encodé en base64, préfixé par « v1, »

Filtrage des événements

CoreStandardWebhook envoie TOUS les événements Infrahub (pas de filtrage par event_type - seul CoreCustomWebhook le supporte). Le receiver filtre côté application :

  • infrahub.artifact.created/updated : commit ciblé de l'artifact concerné
  • infrahub.branch.merged / proposed_change.merged : scan complet via GraphQL
  • infrahub.node.created/updated : traité comme merge si kind = CoreArtifact

Debounce

Un merge de branche déclenche N événements artifact (un par device). Le mécanisme de debounce attend 15 secondes après le dernier événement avant de lancer le sync - un seul traitement quelle que soit la taille de la fleet.


Le deploy script - 5 phases

Phase 1 - Sauvegarde : récupère le running-config de chaque device via eAPI. Point de rollback si le NRFU échoue.

Phase 2 - Push : pousse la config via eAPI (configure replace terminal:). Remplacement atomique.

Phase 3 - NRFU : vérifie que les sessions BGP sont Established (max 30s). Si un peer n'est pas Established → FAIL.

Phase 4 - Rollback : si NRFU échoue, restaure les running-configs sauvegardés en phase 1.

Phase 5 - Circuit breaker : désactive l'auto-sync ArgoCD (spec.syncPolicy.automated → null). Empêche selfHeal: true de reboucler. Réactivé après un NRFU réussi.

Le Job PostSync utilise backoffLimit: 0 et hostNetwork: true. Le RBAC inclut les permissions pour patcher les Applications ArgoCD (circuit breaker).


Le template Jinja2 et la query GraphQL

La query GraphQL récupère toutes les données d'un device. Le template Jinja2 génère une config EOS complète encapsulée dans un ConfigMap K8s : sections statiques (username, aaa, Management0) et dynamiques (interfaces, BGP, prefix-lists).

L'artifact definition dans .infrahub.yml lie la query au template et cible le groupe eos_devices.


Scénario rollback en détail

inject_error.py passe par le pipeline complet Infrahub :

  1. Trouve leaf3 et vérifie son ASN actuel
  2. Crée une branche Infrahub « break-leaf3 »
  3. Modifie l'ASN à 65099 sur cette branche
  4. Crée un Proposed Change
  5. Attend la génération des artifacts
  6. Merge la branche via BranchMerge

Le merge déclenche : webhook → Gitea commit → ArgoCD sync → deploy → NRFU FAIL → rollback → circuit breaker.

ArgoCD - deploy job en erreur ArgoCD - deploy job en erreur

Logs : NRFU FAIL, rollback automatique, circuit breaker Logs : NRFU FAIL, rollback automatique, circuit breaker

ArgoCD - Sync Failed, auto-sync désactivé ArgoCD - Sync Failed, auto-sync désactivé

ArgoCD - OutOfSync, auto-sync disabled ArgoCD - OutOfSync, auto-sync disabled

fix_intent.py corrige la source de vérité : met à jour l'ASN à 65003 sur main, trigger la régénération des artifacts. Après correction, sync manuel → NRFU passe → auto-sync réactivé.

ArgoCD - Synced/Healthy après correction de l'intent ArgoCD - Synced/Healthy après correction de l'intent


Scénario drift CLI

  1. SSH sur leaf3 → no router bgp 65003router bgp 65099
  2. BGP casse (leaf3 en Active)
  3. Forcer un sync : argocd app sync network-configs --force
  4. Le deploy job exécute configure replace → changement CLI écrasé → BGP revient

La détection du drift device-level n'est pas temps-réel - elle dépend du prochain sync ArgoCD. En production, on ajouterait des audits périodiques ou une intégration CVP.

ContainerLab - 5 devices ContainerLab - 5 devices

Infrahub - Proposed Changes Infrahub - Proposed Changes

Artifact diff - config-leaf3.yaml Artifact diff - config-leaf3.yaml

Artifact diff - spines avec Ethernet3 Artifact diff - spines avec Ethernet3

ArgoCD - syncing après commit ArgoCD - syncing après commit

Infrahub - 5 devices dans main Infrahub - 5 devices dans main

spine2 - 3 peers BGP Established spine2 - 3 peers BGP Established


Teardown

Le script teardown.sh gère le nettoyage complet : destruction ContainerLab, conteneurs orphelins, charts Helm, finalizers ArgoCD, namespaces, CRDs, PVCs, réseau Docker, restauration de topology.yml.


Troubleshooting

Conteneurs cEOS zombies (WSL2) : sudo pkill -9 -f Ceos puis sudo docker rm -f. Dernier recours : wsl --shutdown depuis Windows.

Warning ArgoCD finalizer : warning K3S, pas une erreur. Le nom est valide.

Auto-review Infrahub : un utilisateur ne peut pas approuver son propre Proposed Change. Le merge sans approbation est possible via le bouton Merge de l'UI ou --auto-merge.


Ce lab est un point de départ. L'assurance continue - télémétrie, détection de drift en temps réel, remédiation automatique - fera l'objet d'un prochain volet. Nous rappelons également que de nombreuses fonctionnalités dans les différents produits utilisés ici, peuvent être utilisées pour renforcer un tel pipeline de manière globale.


Audric Vernet - Architecte logiciels NXO / Team NANO

Partager :