Home/Modul 6

🎯 Modul 6: VXLAN as Code - Das Hauptmodul

⏱️ Dauer: ca. 75 Minuten | Das Finale! Hier kommt alles zusammen: Git, GitLab, Docker, CI/CD und Nexus Dashboard. Am Ende deployen Sie Ihre VXLAN-Fabric vollständig automatisiert mit echtem Infrastructure as Code.

Teil 1: VXLAN/EVPN Architektur Recap

Bevor wir in den Code eintauchen, frischen wir unser Wissen über VXLAN/EVPN auf. Stellen Sie sich vor, Sie bauen ein modernes Rechenzentrum – wie ein Architekt, der erst den Bauplan versteht, bevor er mit der Automatisierung beginnt.

Die Spine-Leaf Architektur 🌳

Traditionelle 3-Tier-Architekturen (Core-Distribution-Access) sind wie verstopfte Autobahnen – zu viele Hops, zu viele Engpässe. Spine-Leaf ist wie ein U-Bahn-Netz: Von jeder Station kommt man mit maximal 2 Hops überall hin.


                    ┌─────────┐     ┌─────────┐
                    │ Spine-1 │     │ Spine-2 │     ← Spine Layer
                    └────┬────┘     └────┬────┘       (Routing, BGP)
                         │   ╲     ╱     │
                         │    ╲   ╱      │
                         │     ╲ ╱       │            ← Full Mesh
                         │     ╱ ╲       │
                         │    ╱   ╲      │
                    ┌────┴───┐     ┌────┴───┐
                    │ Leaf-1 │     │ Leaf-2 │       ← Leaf Layer
                    └────┬───┘     └────┬───┘         (Server Anbindung)
                         │              │
                    ┌────┴────┐    ┌────┴────┐
                    │ Server  │    │ Server  │      ← Compute
                    └─────────┘    └─────────┘
        
ℹ️Die Analogie: Pizza-Lieferdienst

Spine = Hauptstraßen: Schnelle Verbindungen zwischen Stadtteilen
Leaf = Seitenstraßen: Dort wo die Häuser (Server) sind
VXLAN Tunnel = Geheime Abkürzungen: Direkte Wege durch die Stadt

Underlay vs. Overlay – Die zwei Schichten

🔌 Underlay (Physisch)

  • • IP-Routing zwischen Switches
  • • OSPF oder IS-IS als IGP
  • • BGP EVPN für MAC/IP Learning
  • • PIM/IGMP für BUM Traffic
  • Motto: "Ich weiß, wie ich zu jedem Switch komme"

☁️ Overlay (Virtuell)

  • • VXLAN Tunnel über das Underlay
  • • VNI = VLAN-ID auf Steroiden (24-bit!)
  • • VTEP = Tunnel-Endpunkt auf Leafs
  • • VRFs für Mandantentrennung
  • Motto: "Mir egal wie – Hauptsache mein Traffic kommt an"
📄 VXLAN Tunnel Konzept

┌──────────────────────────────────────────────────────────────────┐
│                        VXLAN Header                               │
├──────────────────────────────────────────────────────────────────┤
│ Outer Ethernet │ Outer IP │ UDP:4789 │ VXLAN │ Inner Frame       │
│   (Underlay)   │(Src→Dst) │          │  VNI  │   (Original)      │
└──────────────────────────────────────────────────────────────────┘

Original Frame: [MAC-A] → [MAC-B] | VLAN 100

Nach VXLAN-Encapsulation:
[VTEP-1 MAC] → [VTEP-2 MAC] | [VTEP-1 IP] → [VTEP-2 IP] | VNI 10100 | [Original Frame]

💡 Der innere Frame bleibt unverändert - wird nur "eingepackt"!

Teil 2: Nexus Dashboard Fabric Controller (NDFC)

NDFC ist das "Gehirn" Ihrer VXLAN-Fabric. Früher hieß es DCNM (Data Center Network Manager) – jetzt ist es Teil der Nexus Dashboard Plattform.

Was macht NDFC eigentlich?

🏗️
Fabric Management

Switches hinzufügen, Rollen zuweisen, Underlay automatisch konfigurieren

🌐
Overlay Provisioning

VRFs, Networks, VNIs – alles über die GUI oder API

📊
Monitoring & Visibility

Topology View, Config Drift Detection, Health Monitoring

NDFC Workflow: Die 3 Phasen

1️⃣ PENDING
2️⃣ STAGED
3️⃣ DEPLOYED

Änderungen werden erst "staged" und dann explizit deployed – wie bei Git!

⚠️Wichtig: Deploy nicht vergessen!

Der häufigste Anfängerfehler: Config erstellen, aber vergessen auf "Deploy" zu klicken. In NDFC heißt das: Recalculate & Deploy. Erst dann landen die Änderungen auf den Switches!

Teil 3: Network as Code (NaC) – Das Konzept

Jetzt kommen wir zum Kern dieses Moduls: Network as Code. Aber was bedeutet das eigentlich?

Die Evolution: Von CLI zu Code

ÄraMethodeProblem
🦕 1990erCLI per TelnetKein Audit, Copy-Paste-Fehler
🖥️ 2000erGUI-basierte ToolsKlick-Orgien, nicht reproduzierbar
📜 2010erScripts (Python, Ansible)Imperative "Wie"-Logik, komplex
🚀 2020erNetwork as CodeDeklarativ: "Was" statt "Wie" ✅

Imperativ vs. Deklarativ

📄 ❌ Imperativ (traditionell)
# Wie komme ich zum Ziel?
ssh admin@switch1
config t
vlan 100
  name Web-Server
exit
interface Eth1/1
  switchport access vlan 100
exit
# ... 50 weitere Befehle
# Und jetzt für Switch 2, 3, 4...
📄 ✅ Deklarativ (NaC)
# Was will ich haben?
networks:
  - name: Web-Server
    vlan_id: 100
    vrf: PROD
    switches:
      - leaf1
      - leaf2

# Das "Wie" übernimmt Ansible + NDFC
ℹ️Die Küchen-Analogie

Imperativ: "Nimm Mehl, Eier, Milch. Verrühre 3 Minuten. Erhitze Pfanne auf 180°. Gieße 50ml Teig..."

Deklarativ: "Ich hätte gerne Pfannkuchen." 🥞

Network as Code ist wie ein Restaurant: Sie bestellen das Ergebnis, der Koch (Ansible) weiß, wie man es zubereitet.

Die Single Source of Truth

Bei NaC gibt es eine einzige Quelle der Wahrheit: Ihre YAML-Dateien in Git. Nicht die Switch-Config. Nicht die NDFC-GUI. Nur das Git-Repository.

📄 Der NaC Workflow

┌─────────────────────────────────────────────────────────────────┐
│                                                                  │
│   📝 YAML Files      →   🦊 Git/GitLab   →   ⚙️ CI/CD Pipeline  │
│   (Data Model)            (Versioning)       (Automation)        │
│                                                                  │
│                              ↓                                   │
│                                                                  │
│   📊 NDFC            ←   🤖 Ansible      ←   🐳 Docker          │
│   (Controller)           (Execution)         (Environment)       │
│                                                                  │
│                              ↓                                   │
│                                                                  │
│                       🔌 Nexus Switches                          │
│                       (Config deployed!)                         │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Teil 4: Das Data Model im Detail

Das Data Model ist das Herzstück von Network as Code. Es beschreibt WAS Sie haben wollen – in einer strukturierten YAML-Datei.

Die Hierarchie verstehen

📄 Data Model Struktur

vxlan/
├── topology/
│   └── switches          # Welche Switches gehören zur Fabric?
│       ├── serial_number # Eindeutige ID des Switches
│       ├── role          # spine, leaf, border
│       └── management    # IP-Adressen, Gateway
│
├── underlay/
│   ├── general           # Fabric-weite Settings
│   └── interfaces        # Physische Links
│
└── overlay/
    ├── vrfs              # VRF-Definitionen
    ├── networks          # L2/L3 Networks
    └── attach_groups     # Wo werden Networks/VRFs deployed?

4.1 Topology: Switches definieren

Jeder Switch wird über seine Serial Number identifiziert – nicht über den Hostnamen oder die IP-Adresse. Das ist wie der Personalausweis des Switches.

📄 data/vxlan.yaml - Topology Section
vxlan:
  topology:
    switches:
      # Spine Switches
      - name: dc1-spine1
        serial_number: FDO24261WAT    # ← Wichtig! Von "show inventory" oder NDFC
        role: spine
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.11
          
      - name: dc1-spine2
        serial_number: FDO24261WAU
        role: spine
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.12
          
      # Leaf Switches
      - name: dc1-leaf1
        serial_number: FDO24261WAV
        role: leaf
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.21
          
      - name: dc1-leaf2
        serial_number: FDO24261WAW
        role: leaf
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.22
🔧🔍 Übung 1: Serial Numbers ermitteln

Wie finden Sie die Serial Number eines Switches? Mehrere Wege:

# Option 1: Direkt auf dem Switch
ssh admin@switch
show inventory

# Option 2: Aus NDFC GUI
# Fabric → Switches → Klick auf Switch → Details

# Option 3: Über NDFC API
curl -k -u admin:password \
  "https://ndfc.lab.local/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/inventory/switches" \
  | jq '.[] | {name: .hostName, serial: .serialNumber}'

Notieren Sie sich die Serial Numbers Ihrer Lab-Switches!

4.2 Overlay: VRFs definieren

VRFs (Virtual Routing and Forwarding) ermöglichen Mandantentrennung. Jeder VRF ist wie ein eigenes virtuelles Netzwerk innerhalb der Fabric.

📄 data/vxlan.yaml - VRFs Section
vxlan:
  overlay:
    vrfs:
      # Produktion VRF
      - name: VRF_PROD
        vrf_id: 150001                    # L3 VNI für den VRF
        vlan_id: 2001                     # SVI VLAN für den VRF
        vrf_attach_group: all_leafs       # Auf welchen Switches deployen?
        description: "Production Environment"
        
      # Entwicklung VRF  
      - name: VRF_DEV
        vrf_id: 150002
        vlan_id: 2002
        vrf_attach_group: all_leafs
        description: "Development Environment"
        
      # DMZ VRF
      - name: VRF_DMZ
        vrf_id: 150003
        vlan_id: 2003
        vrf_attach_group: border_leafs    # Nur auf Border Leafs
        description: "DMZ for external access"

4.3 Overlay: Networks definieren

Networks sind die eigentlichen VLANs/VNIs, in denen Ihre Server leben. Jedes Network gehört zu einem VRF.

📄 data/vxlan.yaml - Networks Section
vxlan:
  overlay:
    networks:
      # Web-Server Netzwerk
      - name: NET_Web_Servers
        vrf_name: VRF_PROD                # Gehört zum PROD VRF
        net_id: 130001                    # L2 VNI
        vlan_id: 2301                     # Access VLAN
        vlan_name: Web-Servers
        gw_ip_address: "192.168.10.1/24"  # Anycast Gateway
        network_attach_group: all_leafs
        description: "Web Server Segment"
        
      # Datenbank Netzwerk
      - name: NET_Databases
        vrf_name: VRF_PROD
        net_id: 130002
        vlan_id: 2302
        vlan_name: Databases
        gw_ip_address: "192.168.20.1/24"
        network_attach_group: db_leafs    # Nur auf bestimmten Leafs
        description: "Database Segment"
        
      # Dev Test Netzwerk
      - name: NET_Dev_Test
        vrf_name: VRF_DEV
        net_id: 130101
        vlan_id: 2401
        vlan_name: Dev-Testing
        gw_ip_address: "192.168.100.1/24"
        network_attach_group: all_leafs
        description: "Development Testing"

4.4 Network Attach Groups

Attach Groups definieren, WO Networks und VRFs deployed werden. Statt jeden Switch einzeln zu nennen, erstellen Sie wiederverwendbare Gruppen.

📄 data/vxlan.yaml - Attach Groups
vxlan:
  overlay:
    network_attach_groups:
      # Alle Leafs
      - name: all_leafs
        switches:
          - hostname: dc1-leaf1
            ports: []                      # Keine spezifischen Ports = Trunk
          - hostname: dc1-leaf2
            ports: []
            
      # Nur Leafs mit Datenbank-Servern
      - name: db_leafs
        switches:
          - hostname: dc1-leaf1
            ports: [Ethernet1/10, Ethernet1/11]   # Spezifische Access Ports
            
      # Leafs mit Server-Anbindung + Ports
      - name: web_leafs
        switches:
          - hostname: dc1-leaf1
            ports: [Ethernet1/13, Ethernet1/14]
          - hostname: dc1-leaf2
            ports: [Ethernet1/13, Ethernet1/14]
            
    # VRF Attach Groups (separart für VRFs)
    vrf_attach_groups:
      - name: all_leafs
        switches:
          - hostname: dc1-leaf1
          - hostname: dc1-leaf2
          
      - name: border_leafs
        switches:
          - hostname: dc1-leaf1             # Border Leaf für External Routing
ℹ️💡 Pro-Tipp: Attach Groups

Nutzen Sie Attach Groups wie Kubernetes Labels: Definieren Sie einmal "db_leafs" oder "web_leafs", und referenzieren Sie sie überall. Wenn sich später die Zuordnung ändert, passen Sie nur die Gruppe an – nicht jedes Network einzeln.

Teil 5: Die Ansible Roles verstehen

Das NaC Framework nutzt 4 Hauptroles, die in einer bestimmten Reihenfolge ausgeführt werden:

1. VALIDATE
Syntax & Schema
2. CREATE
Build & Stage
3. DEPLOY
Push to Devices
4. REMOVE
Cleanup (optional)

Role 1: VALIDATE

Prüft, ob Ihr Data Model syntaktisch korrekt ist und alle Referenzen stimmen.

# Was wird validiert:
# ✓ YAML Syntax korrekt?
# ✓ Alle Pflichtfelder vorhanden?
# ✓ VRF existiert, wenn Network ihn referenziert?
# ✓ Attach Group existiert?
# ✓ Keine doppelten VNIs oder VLANs?

Role 2: CREATE

Erstellt die Konfiguration in NDFC (staged, noch nicht deployed).

# Was passiert:
# → Fabric wird erstellt/aktualisiert
# → Switches werden der Fabric hinzugefügt
# → VRFs werden angelegt (Status: PENDING)
# → Networks werden angelegt (Status: PENDING)
# → Attach-Beziehungen werden definiert

Role 3: DEPLOY

Pushed die staged Config auf die echten Switches.

# Was passiert:
# → NDFC generiert die CLI-Befehle
# → Config wird auf Switches gepushed
# → Status wechselt von PENDING → DEPLOYED
# → Switches erhalten die VLANs, VRFs, VNIs

Role 4: REMOVE (Optional)

Deklaratives Aufräumen: Entfernt alles, was NICHT im Data Model steht.

⚠️⚠️ REMOVE ist mächtig!

Wenn Sie ein Network aus dem Data Model löschen und dann den REMOVE-Role ausführen, wird es aus NDFC und von den Switches gelöscht. Das ist der "deklarative" Ansatz: Das Data Model ist die Wahrheit.

Teil 6: Inventory und Playbook Struktur

Das Ansible Inventory

Das Inventory definiert, wie Ansible sich mit NDFC verbindet.

📄 inventory.yaml
---
all:
  hosts:
    ndfc:
      ansible_host: "{{ lookup('env', 'ND_HOST') }}"
      ansible_user: "{{ lookup('env', 'ND_USERNAME') }}"
      ansible_password: "{{ lookup('env', 'ND_PASSWORD') }}"
      ansible_connection: ansible.netcommon.httpapi
      ansible_httpapi_port: 443
      ansible_httpapi_use_ssl: true
      ansible_httpapi_validate_certs: false
      ansible_network_os: cisco.dcnm.dcnm
      
      # NaC-spezifische Variablen
      vxlan_fabric: "{{ lookup('env', 'FABRIC_NAME') | default('MyFabric') }}"
      nac_data_model: "data/"            # Pfad zu den YAML-Dateien

Das Haupt-Playbook

📄 vxlan.yaml
---
# VXLAN Network as Code Playbook
- name: NaC for VXLAN EVPN
  hosts: ndfc
  gather_facts: false
  
  roles:
    # 1. Validierung des Data Models
    - role: cisco.nac_dc_vxlan.validate
      tags: [validate]
      
    # 2. Konfiguration in NDFC erstellen  
    - role: cisco.nac_dc_vxlan.create
      tags: [create]
      
    # 3. Config auf Switches deployen
    - role: cisco.nac_dc_vxlan.deploy
      tags: [deploy]
      
    # 4. Optional: Nicht definiertes entfernen
    # - role: cisco.nac_dc_vxlan.remove
    #   tags: [remove]

Die Projektstruktur

📄 Repository Struktur
vxlan-fabric/
├── ansible.cfg              # Ansible-Konfiguration
├── inventory.yaml           # NDFC Connection
├── vxlan.yaml              # Haupt-Playbook
│
├── data/                    # 📂 DATA MODEL (Single Source of Truth)
│   ├── vxlan.yaml          # Haupt-Datei mit allem
│   └── optional/           # Oder aufgeteilt:
│       ├── topology.yaml   #   - Nur Switches
│       ├── vrfs.yaml       #   - Nur VRFs
│       └── networks.yaml   #   - Nur Networks
│
├── .gitlab-ci.yml          # CI/CD Pipeline
└── .env.example            # Environment Variables Template

Teil 7: Environment Variables für Credentials

⚠️🔐 NIEMALS Passwörter im Code!

Credentials gehören in Environment Variables – NICHT in Git. Das ist die goldene Regel von DevSecOps.

Die wichtigsten Variables

📄 .env.example (NICHT committen!)
# NDFC/Nexus Dashboard Connection
export ND_HOST="ndfc.lab.local"
export ND_USERNAME="admin"
export ND_PASSWORD="SuperSecretPassword123!"

# Fabric Settings
export FABRIC_NAME="DC1-VXLAN-Fabric"

# Optional: Ansible Settings
export ANSIBLE_HOST_KEY_CHECKING=false
export ANSIBLE_PYTHON_INTERPRETER=auto_silent

So laden Sie die Variables

# Option 1: Manuell vor Ausführung
source .env
ansible-playbook -i inventory.yaml vxlan.yaml

# Option 2: In der CI/CD Pipeline (GitLab)
# Variables werden in Settings → CI/CD → Variables definiert

# Option 3: Mit einem .envrc (direnv)
# Automatisches Laden beim Betreten des Verzeichnisses
🔧🔍 Übung 2: Environment Setup

Richten Sie Ihre lokale Umgebung ein:

# 1. .env Datei erstellen
cp .env.example .env

# 2. Credentials eintragen (IHREN NDFC!)
nano .env

# 3. Testen ob es funktioniert
source .env
echo "NDFC Host: $ND_HOST"

# 4. Sicherstellen dass .env NICHT in Git landet
echo ".env" >> .gitignore

Teil 8: Hands-On Praxis-Übungen

🎯 Ab hier wird es praktisch! Öffnen Sie Ihr Terminal, VS Code und den NDFC Browser. Wir arbeiten mit echten Switches.

🔧🔧 Übung 3: Data Model erkunden

Ziel: Die YAML-Struktur verstehen

# 1. Repository klonen
git clone https://gitlab.lab.local/schulung/vxlan-nac.git
cd vxlan-nac

# 2. Struktur anschauen
tree .
ls -la data/

# 3. Data Model öffnen und verstehen
cat data/vxlan.yaml

# 4. In VS Code öffnen für bessere Übersicht
code .

Fragen zum Beantworten:

  • Wie viele Switches sind definiert?
  • Welche VRFs gibt es?
  • Welches Network hat die VLAN ID 2301?
🔧🔧 Übung 4: Switch zur Fabric hinzufügen

Ziel: Einen neuen Leaf Switch im Data Model definieren

📄 data/vxlan.yaml ergänzen
# Unter vxlan.topology.switches hinzufügen:

      - name: dc1-leaf3
        serial_number: FDO24261WAX    # ← Ihre echte Serial Number!
        role: leaf
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.23
# Änderung committen
git add data/vxlan.yaml
git commit -m "Add dc1-leaf3 to fabric"

# NOCH NICHT pushen - erst validieren!
🔧🔧 Übung 5: Neuen VRF erstellen

Ziel: Einen VRF für das IoT-Segment anlegen

📄 data/vxlan.yaml ergänzen
# Unter vxlan.overlay.vrfs hinzufügen:

      - name: VRF_IOT
        vrf_id: 150004
        vlan_id: 2004
        vrf_attach_group: all_leafs
        description: "IoT Device Segment"
# Änderung committen
git add data/vxlan.yaml
git commit -m "Add VRF_IOT for IoT devices"
🔧🔧 Übung 6: Network im neuen VRF erstellen

Ziel: Ein Netzwerk für IoT-Sensoren

📄 data/vxlan.yaml ergänzen
# Unter vxlan.overlay.networks hinzufügen:

      - name: NET_IoT_Sensors
        vrf_name: VRF_IOT
        net_id: 130201
        vlan_id: 2501
        vlan_name: IoT-Sensors
        gw_ip_address: "192.168.200.1/24"
        network_attach_group: all_leafs
        description: "IoT Sensor Network"
git add data/vxlan.yaml
git commit -m "Add IoT Sensor network in VRF_IOT"
🔧🔧 Übung 7: Playbook ausführen

Ziel: Die Änderungen validieren und deployen

# 1. Environment laden
source .env

# 2. Nur VALIDIEREN (kein Deployment)
ansible-playbook -i inventory.yaml vxlan.yaml --tags validate

# 3. Dry-Run: Was WÜRDE passieren?
ansible-playbook -i inventory.yaml vxlan.yaml --tags create --check

# 4. CREATE: In NDFC erstellen (staged)
ansible-playbook -i inventory.yaml vxlan.yaml --tags create

# 5. DEPLOY: Auf Switches pushen
ansible-playbook -i inventory.yaml vxlan.yaml --tags deploy

Tipp: Beobachten Sie parallel die NDFC-GUI unter Fabric → Networks. Sie sehen, wie sich der Status ändert!

🔧🔧 Übung 8: In NDFC verifizieren

Ziel: Die deployten Änderungen in der GUI überprüfen

  1. Öffnen Sie https://ndfc.lab.local im Browser
  2. Navigieren Sie zu Fabric → [Ihre Fabric]
  3. Klicken Sie auf VRFs – Sehen Sie VRF_IOT?
  4. Klicken Sie auf Networks – Sehen Sie NET_IoT_Sensors?
  5. Öffnen Sie einen Leaf Switch → Show Run
  6. Suchen Sie nach vlan 2501 und vrf VRF_IOT
# Alternativ per CLI auf dem Switch prüfen
ssh admin@dc1-leaf1
show vlan brief | grep 2501
show vrf VRF_IOT
show nve peers
🔧🔧 Übung 9: Rollback durchführen

Ziel: Eine Änderung rückgängig machen

# 1. Letzten Commit anzeigen
git log --oneline -3

# 2. Änderung rückgängig machen (IoT Network entfernen)
# Option A: Im Data Model löschen + REMOVE role
# Option B: Git revert

# Option B demonstriert:
git revert HEAD --no-edit    # Letzten Commit rückgängig

# 3. Änderung deployen
ansible-playbook -i inventory.yaml vxlan.yaml --tags validate,create,deploy

# 4. REMOVE role ausführen (löscht nicht mehr definiertes)
# ACHTUNG: Nur wenn Sie wissen was Sie tun!
# ansible-playbook -i inventory.yaml vxlan.yaml --tags remove

Git Revert vs. Remove Role:
Git Revert ändert nur den Code. Die Remove Role löscht in NDFC.

Teil 9: End-to-End Demo – Komplette Fabric deployen

🎬 Showtime! Jetzt setzen wir alles zusammen: Ein komplettes Data Model für eine produktionsreife VXLAN-Fabric.

Das komplette Data Model

📄 data/vxlan.yaml - Komplette Fabric
---
# ============================================================
# VXLAN EVPN Fabric - Network as Code Data Model
# Single Source of Truth für DC1-VXLAN-Fabric
# ============================================================

vxlan:
  # ----------------------------------------------------------
  # TOPOLOGY: Physische Switches der Fabric
  # ----------------------------------------------------------
  topology:
    switches:
      # Spine Layer
      - name: dc1-spine1
        serial_number: FDO24261WAT
        role: spine
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.11
          
      - name: dc1-spine2
        serial_number: FDO24261WAU
        role: spine
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.12
          
      # Leaf Layer
      - name: dc1-leaf1
        serial_number: FDO24261WAV
        role: leaf
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.21
          
      - name: dc1-leaf2
        serial_number: FDO24261WAW
        role: leaf
        management:
          default_gateway_v4: 10.1.1.1
          management_ipv4_address: 10.1.1.22

  # ----------------------------------------------------------
  # OVERLAY: Virtuelle Netzwerk-Konstrukte
  # ----------------------------------------------------------
  overlay:
    # VRF Definitions
    vrfs:
      - name: VRF_PROD
        vrf_id: 150001
        vlan_id: 2001
        vrf_attach_group: all_leafs
        description: "Production Workloads"
        
      - name: VRF_DEV
        vrf_id: 150002
        vlan_id: 2002
        vrf_attach_group: all_leafs
        description: "Development Environment"
        
      - name: VRF_MGMT
        vrf_id: 150003
        vlan_id: 2003
        vrf_attach_group: all_leafs
        description: "Management Traffic"

    # Network Definitions
    networks:
      # Production Networks
      - name: NET_Web_Frontend
        vrf_name: VRF_PROD
        net_id: 130001
        vlan_id: 2301
        vlan_name: Web-Frontend
        gw_ip_address: "10.10.1.1/24"
        network_attach_group: all_leafs
        description: "Web Frontend Servers"
        
      - name: NET_App_Backend
        vrf_name: VRF_PROD
        net_id: 130002
        vlan_id: 2302
        vlan_name: App-Backend
        gw_ip_address: "10.10.2.1/24"
        network_attach_group: all_leafs
        description: "Application Backend"
        
      - name: NET_Database
        vrf_name: VRF_PROD
        net_id: 130003
        vlan_id: 2303
        vlan_name: Databases
        gw_ip_address: "10.10.3.1/24"
        network_attach_group: db_leafs
        description: "Database Segment"
        
      # Development Networks
      - name: NET_Dev_Apps
        vrf_name: VRF_DEV
        net_id: 130101
        vlan_id: 2401
        vlan_name: Dev-Apps
        gw_ip_address: "10.20.1.1/24"
        network_attach_group: all_leafs
        description: "Development Applications"
        
      # Management Networks
      - name: NET_Infra_Mgmt
        vrf_name: VRF_MGMT
        net_id: 130201
        vlan_id: 2501
        vlan_name: Infra-Mgmt
        gw_ip_address: "10.30.1.1/24"
        network_attach_group: all_leafs
        description: "Infrastructure Management"

    # Attach Groups
    network_attach_groups:
      - name: all_leafs
        switches:
          - hostname: dc1-leaf1
            ports: []
          - hostname: dc1-leaf2
            ports: []
            
      - name: db_leafs
        switches:
          - hostname: dc1-leaf1
            ports: [Ethernet1/10]
            
    vrf_attach_groups:
      - name: all_leafs
        switches:
          - hostname: dc1-leaf1
          - hostname: dc1-leaf2

Der Deployment-Ablauf

📄 deploy.sh - Komplettes Deployment
#!/bin/bash
# ============================================================
# VXLAN Fabric Deployment Script
# ============================================================

set -e  # Exit on error

echo "🚀 Starting VXLAN Fabric Deployment..."

# 1. Environment laden
echo "📦 Loading environment..."
source .env

# 2. Validierung
echo "✅ Validating data model..."
ansible-playbook -i inventory.yaml vxlan.yaml --tags validate
if [ $? -ne 0 ]; then
    echo "❌ Validation failed! Aborting."
    exit 1
fi

# 3. Create in NDFC
echo "🏗️ Creating configuration in NDFC..."
ansible-playbook -i inventory.yaml vxlan.yaml --tags create

# 4. Deploy to Switches
echo "🚀 Deploying to switches..."
ansible-playbook -i inventory.yaml vxlan.yaml --tags deploy

# 5. Verification
echo "🔍 Verifying deployment..."
ansible-playbook -i inventory.yaml verify.yaml

echo "✅ Deployment complete!"
echo "📊 Check NDFC: https://$ND_HOST"

Die CI/CD Pipeline

📄 .gitlab-ci.yml
---
# GitLab CI/CD Pipeline für VXLAN Network as Code
stages:
  - validate
  - test
  - stage
  - deploy
  - verify

variables:
  ANSIBLE_HOST_KEY_CHECKING: "false"
  ANSIBLE_FORCE_COLOR: "true"

default:
  image: ghcr.io/netascode/nac-dc-vxlan:latest
  before_script:
    - ansible --version
    - ansible-galaxy collection list

# ============================================================
# Stage 1: VALIDATE
# ============================================================
validate:
  stage: validate
  script:
    - yamllint data/
    - ansible-playbook -i inventory.yaml vxlan.yaml --tags validate
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

# ============================================================
# Stage 2: TEST (Dry-Run)
# ============================================================
dry-run:
  stage: test
  script:
    - ansible-playbook -i inventory.yaml vxlan.yaml --tags create --check
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  environment:
    name: staging

# ============================================================
# Stage 3: STAGE (Create in NDFC)
# ============================================================
stage-config:
  stage: stage
  script:
    - ansible-playbook -i inventory.yaml vxlan.yaml --tags create
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  environment:
    name: production

# ============================================================
# Stage 4: DEPLOY (Push to Switches)
# ============================================================
deploy:
  stage: deploy
  script:
    - ansible-playbook -i inventory.yaml vxlan.yaml --tags deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  when: manual  # Manueller Trigger für Safety
  environment:
    name: production
  needs:
    - stage-config

# ============================================================
# Stage 5: VERIFY
# ============================================================
verify:
  stage: verify
  script:
    - ansible-playbook -i inventory.yaml verify.yaml
    - echo "Deployment verified successfully!"
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  needs:
    - deploy

Teil 10: Best Practices & häufige Fehler

✅ Best Practices

Code & Git

  • Atomic Commits: Eine Änderung = ein Commit
  • Aussagekräftige Messages: "Add VRF_IOT" statt "update"
  • Feature Branches: Nie direkt auf main
  • Code Review: Vier-Augen-Prinzip
  • .gitignore: .env, *.retry, __pycache__

Data Model

  • Naming Convention: NET_, VRF_, dc1-leaf1
  • Kommentare: Beschreiben Sie das "Warum"
  • VNI/VLAN Ranges: Dokumentieren und einhalten
  • Attach Groups: Wiederverwendbare Gruppen nutzen
  • Validierung: IMMER vor Deploy!

Deployment

  • Dry-Run First: --check vor echtem Deploy
  • Staging Environment: Erst testen, dann Prod
  • Manual Gate: Deploy-Step mit when: manual
  • Rollback Plan: Git revert + Remove Role
  • Monitoring: NDFC Logs beobachten

Security

  • Env Variables: Credentials NIE im Code
  • GitLab Secrets: Protected Variables nutzen
  • RBAC: Minimale Rechte für Service Accounts
  • Audit Trail: Git History = Dokumentation
  • MFA: Für NDFC und GitLab aktivieren

❌ Häufige Fehler und Lösungen

Fehler: "Serial number not found in fabric"

Der Switch muss erst in NDFC entdeckt werden, bevor NaC ihn managen kann.

# Lösung: Switch in NDFC Discovery
# NDFC GUI → Fabric → Add Switches → Enter IP/Credentials
# ODER: Switch muss POAP durchlaufen haben

Fehler: "VRF not found" beim Network erstellen

Das Network referenziert einen VRF, der nicht existiert.

# Lösung: Reihenfolge prüfen
# VRF MUSS vor dem Network definiert sein!
vrfs:
  - name: VRF_PROD    # ← Zuerst
    ...
networks:
  - name: NET_Web
    vrf_name: VRF_PROD  # ← Dann referenzieren

Fehler: "Authentication failed"

Credentials stimmen nicht oder Environment Variables nicht geladen.

# Lösung: Environment prüfen
echo $ND_HOST
echo $ND_USERNAME
# Passwort nicht echoen! Aber prüfen ob gesetzt:
[ -z "$ND_PASSWORD" ] && echo "PASSWORD NOT SET!"

# Neu laden:
source .env

Fehler: Config ist "PENDING" aber nicht deployed

CREATE wurde ausgeführt, aber DEPLOY vergessen.

# Lösung: Deploy-Tag hinzufügen
ansible-playbook -i inventory.yaml vxlan.yaml --tags deploy

# Oder beide zusammen:
ansible-playbook -i inventory.yaml vxlan.yaml --tags create,deploy

Fehler: "Duplicate VNI/VLAN"

VNI oder VLAN ID wird bereits verwendet.

# Lösung: Eindeutige IDs verwenden
# VNI Range planen:
# VRFs:     150001 - 150999
# Networks: 130001 - 139999

# In NDFC prüfen welche bereits belegt:
# Fabric → VRFs → VNI Spalte
# Fabric → Networks → VNI Spalte

Zusammenfassung

🎉 Geschafft – Sie sind jetzt ein NaC-Profi!

In diesem Modul haben Sie gelernt:

  • ☑️ VXLAN/EVPN Architektur verstehen
  • ☑️ NDFC als Fabric Controller nutzen
  • ☑️ Network as Code Konzept anwenden
  • ☑️ Data Models in YAML schreiben
  • ☑️ Ansible Roles verstehen und nutzen
  • ☑️ Environment Variables für Security
  • ☑️ Praxis-Übungen durchgeführt
  • ☑️ CI/CD Pipeline konfiguriert
  • ☑️ Best Practices verinnerlicht
  • ☑️ Fehler debuggen können

Der komplette Workflow auf einen Blick


Developer                   GitLab                      NDFC                    Switches
    │                          │                          │                         │
    │  1. Edit YAML           │                          │                         │
    │  2. git commit          │                          │                         │
    │  3. git push ──────────►│                          │                         │
    │                          │  4. Pipeline starts      │                         │
    │                          │  5. Validate ───────────►│                         │
    │                          │  6. Create ─────────────►│  (STAGED)              │
    │                          │  7. Deploy ─────────────►│─────────────────────►  │
    │                          │                          │     (CONFIG PUSHED)    │
    │                          │  8. Verify ◄────────────│◄──────────────────────│
    │  ◄─────── Success! ─────│                          │                         │
    │                          │                          │                         │

Nächste Schritte

Weiterführende Ressourcen

ℹ️💡 Abschluss-Tipp

Der beste Weg zu lernen ist Übung. Nehmen Sie sich Zeit, das Lab durchzugehen. Machen Sie absichtlich Fehler und lernen Sie, sie zu beheben. Und vor allem: Haben Sie Spaß! 🚀