[Phase 2] Define Infrahub Schema for EVPN-VXLAN Fabric #41

Closed
opened 2026-02-05 09:04:30 +00:00 by Damien · 2 comments
Owner

Description

Define the Infrahub schema to model all network fabric objects required for EVPN-VXLAN orchestration, replacing NetBox as the Source of Truth.

Context

Infrahub requires explicit schema definitions for all data objects. This schema forms the foundation for all GraphQL queries and transforms. We can leverage the opsmill/schema-library as a starting point and extend it for EVPN-VXLAN specifics.

Tasks

  • Evaluate schema-library base models (Device, Interface, VLAN, VRF, etc.)
  • Define/extend core infrastructure models
  • Define EVPN-VXLAN specific models
  • Define BGP models
  • Define MLAG models
  • Create schema validation tests
  • Document schema relationships

Schema Components

Core Infrastructure (from schema-library or custom)

# InfraDevice
- name: InfraDevice
  namespace: Infra
  attributes:
    - name: name
      kind: Text
      unique: true
    - name: role
      kind: Dropdown
      choices: [spine, leaf, border-leaf]
    - name: platform
      kind: Text
    - name: router_id
      kind: IPHost
  relationships:
    - name: interfaces
      peer: InfraInterface
      cardinality: many
    - name: site
      peer: LocationSite
      cardinality: one
    - name: asn
      peer: InfraAutonomousSystem
      cardinality: one

VLAN & VXLAN

# InfraVLAN
- name: InfraVLAN
  namespace: Infra
  attributes:
    - name: vlan_id
      kind: Number
    - name: name
      kind: Text
    - name: vni
      kind: Number
      optional: true
    - name: status
      kind: Dropdown
      choices: [active, reserved, deprecated]
  relationships:
    - name: devices
      peer: InfraDevice
      cardinality: many

# InfraVTEP
- name: InfraVTEP
  namespace: Infra
  attributes:
    - name: source_interface
      kind: Text
    - name: udp_port
      kind: Number
      default: 4789
  relationships:
    - name: device
      peer: InfraDevice
      cardinality: one
    - name: loopback
      peer: InfraInterface
      cardinality: one

VRF & L3VNI

# InfraVRF
- name: InfraVRF
  namespace: Infra
  attributes:
    - name: name
      kind: Text
    - name: rd
      kind: Text
      description: "Route Distinguisher"
    - name: l3vni
      kind: Number
      optional: true
  relationships:
    - name: import_targets
      peer: InfraRouteTarget
      cardinality: many
    - name: export_targets
      peer: InfraRouteTarget
      cardinality: many
    - name: devices
      peer: InfraDevice
      cardinality: many

# InfraRouteTarget
- name: InfraRouteTarget
  namespace: Infra
  attributes:
    - name: target
      kind: Text
      description: "Format: ASN:NN or IP:NN"

BGP

# InfraAutonomousSystem
- name: InfraAutonomousSystem
  namespace: Infra
  attributes:
    - name: asn
      kind: Number
    - name: description
      kind: Text
      optional: true

# InfraBGPPeerGroup
- name: InfraBGPPeerGroup
  namespace: Infra
  attributes:
    - name: name
      kind: Text
    - name: remote_as
      kind: Number
      optional: true
    - name: update_source
      kind: Text
      optional: true
    - name: ebgp_multihop
      kind: Number
      optional: true
    - name: send_community
      kind: Dropdown
      choices: [none, standard, extended, both]
  relationships:
    - name: device
      peer: InfraDevice
      cardinality: one

# InfraBGPSession
- name: InfraBGPSession
  namespace: Infra
  attributes:
    - name: peer_address
      kind: IPHost
    - name: peer_asn
      kind: Number
    - name: description
      kind: Text
      optional: true
    - name: enabled
      kind: Boolean
      default: true
  relationships:
    - name: device
      peer: InfraDevice
      cardinality: one
    - name: peer_group
      peer: InfraBGPPeerGroup
      cardinality: one
      optional: true

MLAG

# InfraMlagDomain
- name: InfraMlagDomain
  namespace: Infra
  attributes:
    - name: domain_id
      kind: Text
    - name: virtual_mac
      kind: Text
    - name: peer_vlan
      kind: Number
    - name: dual_primary_enabled
      kind: Boolean
      default: true
    - name: dual_primary_delay
      kind: Number
      default: 10
  relationships:
    - name: devices
      peer: InfraDevice
      cardinality: many
      min_count: 2
      max_count: 2

Output Files

schemas/
├── base.yml           # Core: Device, Interface, IP
├── vlan_vxlan.yml     # VLAN, VTEP, VNI mappings
├── vrf.yml            # VRF, RouteTarget, L3VNI
├── bgp.yml            # AS, PeerGroup, Session
├── mlag.yml           # MLAG Domain
└── extensions.yml     # Custom attributes/relationships

Schema Validation

# .infrahub.yml
schema_tests:
  - name: validate_fabric_schema
    kind: schema-validation

Acceptance Criteria

  • Schema loads without errors in Infrahub
  • All relationships correctly defined
  • GraphQL queries work for all object types
  • Schema supports the reference EVPN-VXLAN topology
  • Documentation includes entity-relationship diagram

Migration Notes (from NetBox)

NetBox Infrahub
Device InfraDevice
Interface InfraInterface
VLAN InfraVLAN
VRF + custom fields InfraVRF with l3vni attribute
netbox-bgp plugin InfraBGPSession, InfraBGPPeerGroup
Custom fields for MLAG InfraMlagDomain
## Description Define the Infrahub schema to model all network fabric objects required for EVPN-VXLAN orchestration, replacing NetBox as the Source of Truth. ## Context Infrahub requires explicit schema definitions for all data objects. This schema forms the foundation for all GraphQL queries and transforms. We can leverage the [opsmill/schema-library](https://github.com/opsmill/schema-library) as a starting point and extend it for EVPN-VXLAN specifics. ## Tasks - [x] Evaluate schema-library base models (Device, Interface, VLAN, VRF, etc.) - [x] Define/extend core infrastructure models - [x] Define EVPN-VXLAN specific models - [x] Define BGP models - [x] Define MLAG models - [x] Create schema validation tests - [ ] Document schema relationships ## Schema Components ### Core Infrastructure (from schema-library or custom) ```yaml # InfraDevice - name: InfraDevice namespace: Infra attributes: - name: name kind: Text unique: true - name: role kind: Dropdown choices: [spine, leaf, border-leaf] - name: platform kind: Text - name: router_id kind: IPHost relationships: - name: interfaces peer: InfraInterface cardinality: many - name: site peer: LocationSite cardinality: one - name: asn peer: InfraAutonomousSystem cardinality: one ``` ### VLAN & VXLAN ```yaml # InfraVLAN - name: InfraVLAN namespace: Infra attributes: - name: vlan_id kind: Number - name: name kind: Text - name: vni kind: Number optional: true - name: status kind: Dropdown choices: [active, reserved, deprecated] relationships: - name: devices peer: InfraDevice cardinality: many # InfraVTEP - name: InfraVTEP namespace: Infra attributes: - name: source_interface kind: Text - name: udp_port kind: Number default: 4789 relationships: - name: device peer: InfraDevice cardinality: one - name: loopback peer: InfraInterface cardinality: one ``` ### VRF & L3VNI ```yaml # InfraVRF - name: InfraVRF namespace: Infra attributes: - name: name kind: Text - name: rd kind: Text description: "Route Distinguisher" - name: l3vni kind: Number optional: true relationships: - name: import_targets peer: InfraRouteTarget cardinality: many - name: export_targets peer: InfraRouteTarget cardinality: many - name: devices peer: InfraDevice cardinality: many # InfraRouteTarget - name: InfraRouteTarget namespace: Infra attributes: - name: target kind: Text description: "Format: ASN:NN or IP:NN" ``` ### BGP ```yaml # InfraAutonomousSystem - name: InfraAutonomousSystem namespace: Infra attributes: - name: asn kind: Number - name: description kind: Text optional: true # InfraBGPPeerGroup - name: InfraBGPPeerGroup namespace: Infra attributes: - name: name kind: Text - name: remote_as kind: Number optional: true - name: update_source kind: Text optional: true - name: ebgp_multihop kind: Number optional: true - name: send_community kind: Dropdown choices: [none, standard, extended, both] relationships: - name: device peer: InfraDevice cardinality: one # InfraBGPSession - name: InfraBGPSession namespace: Infra attributes: - name: peer_address kind: IPHost - name: peer_asn kind: Number - name: description kind: Text optional: true - name: enabled kind: Boolean default: true relationships: - name: device peer: InfraDevice cardinality: one - name: peer_group peer: InfraBGPPeerGroup cardinality: one optional: true ``` ### MLAG ```yaml # InfraMlagDomain - name: InfraMlagDomain namespace: Infra attributes: - name: domain_id kind: Text - name: virtual_mac kind: Text - name: peer_vlan kind: Number - name: dual_primary_enabled kind: Boolean default: true - name: dual_primary_delay kind: Number default: 10 relationships: - name: devices peer: InfraDevice cardinality: many min_count: 2 max_count: 2 ``` ## Output Files ``` schemas/ ├── base.yml # Core: Device, Interface, IP ├── vlan_vxlan.yml # VLAN, VTEP, VNI mappings ├── vrf.yml # VRF, RouteTarget, L3VNI ├── bgp.yml # AS, PeerGroup, Session ├── mlag.yml # MLAG Domain └── extensions.yml # Custom attributes/relationships ``` ## Schema Validation ```yaml # .infrahub.yml schema_tests: - name: validate_fabric_schema kind: schema-validation ``` ## Acceptance Criteria - [ ] Schema loads without errors in Infrahub - [ ] All relationships correctly defined - [ ] GraphQL queries work for all object types - [ ] Schema supports the reference EVPN-VXLAN topology - [ ] Documentation includes entity-relationship diagram ## Migration Notes (from NetBox) | NetBox | Infrahub | |--------|----------| | Device | InfraDevice | | Interface | InfraInterface | | VLAN | InfraVLAN | | VRF + custom fields | InfraVRF with l3vni attribute | | netbox-bgp plugin | InfraBGPSession, InfraBGPPeerGroup | | Custom fields for MLAG | InfraMlagDomain | ## Related - Prerequisite for: #30, #31, #32, #33 (all transforms) - Reference: [opsmill/schema-library](https://github.com/opsmill/schema-library) - Reference: [Infrahub Schema Documentation](https://docs.infrahub.app/topics/schema)
Damien added the phase-2-minimal-reconciler label 2026-02-05 09:04:46 +00:00
Damien added this to the Fabric Orchestrator project 2026-02-05 09:05:56 +00:00
Damien moved this to To Do in Fabric Orchestrator on 2026-02-05 09:06:07 +00:00
Damien added a new dependency 2026-02-05 09:08:20 +00:00
Damien added a new dependency 2026-02-05 09:08:40 +00:00
Damien added a new dependency 2026-02-05 09:08:49 +00:00
Damien referenced this issue from a commit 2026-02-05 15:53:13 +00:00
Damien referenced this issue from a commit 2026-02-05 15:53:34 +00:00
Author
Owner

Initial Schema Proposal

Branch created: feature/41-infrahub-schema

Schema Structure

schemas/
├── base.yml          # Device, Interface types, IP, Platform, Site
├── vlan_vxlan.yml    # VLAN, VNI, VTEP, EVPN Instance
├── vrf.yml           # VRF, Route Target, VRF assignments
├── bgp.yml           # AS, BGP Config, Peer Groups, Sessions
├── mlag.yml          # MLAG Domain, Peer Config, MLAG Interfaces
├── extensions.yml    # Fabric, Underlay Links, Host Connections
└── README.md         # Documentation with ERD

Key Design Choices

  1. Interface Generics: All interface types (Ethernet, Loopback, Vlan, Lag, Vxlan) inherit from InfraInterface generic for polymorphic queries

  2. MLAG Domain Model: MLAG is a domain with exactly 2 devices, plus per-device config (MlagPeerConfig) and shared MLAG interfaces (MlagInterface)

  3. BGP Hierarchy: BGPRouterConfigBGPPeerGroupBGPSession enables template-based configuration matching Arista EOS structure

  4. EVPN per VLAN: EVPNInstance allows device-specific RD/RT while referencing common VLAN/VNI

Mapping to arista-evpn-vxlan-clab

Lab Component Schema Model
spine1/2 (AS 65000) InfraDevice + InfraAutonomousSystem
leaf1-8 (AS 65001-65004) InfraDevice + InfraAutonomousSystem
VLAN 40 + VNI 110040 InfraVLAN + InfraVNI + InfraEVPNInstance
leaf1+leaf2 MLAG InfraMlagDomain + 2x InfraMlagPeerConfig
Port-Channel999 (peer-link) InfraInterfaceLag
underlay/evpn peer-groups InfraBGPPeerGroup

Next Steps

  • Review schema structure
  • Test loading into Infrahub dev instance
  • Add sample data for validation
  • Create Jinja2 transforms (issues #30-33)
## Initial Schema Proposal Branch created: `feature/41-infrahub-schema` ### Schema Structure ``` schemas/ ├── base.yml # Device, Interface types, IP, Platform, Site ├── vlan_vxlan.yml # VLAN, VNI, VTEP, EVPN Instance ├── vrf.yml # VRF, Route Target, VRF assignments ├── bgp.yml # AS, BGP Config, Peer Groups, Sessions ├── mlag.yml # MLAG Domain, Peer Config, MLAG Interfaces ├── extensions.yml # Fabric, Underlay Links, Host Connections └── README.md # Documentation with ERD ``` ### Key Design Choices 1. **Interface Generics**: All interface types (`Ethernet`, `Loopback`, `Vlan`, `Lag`, `Vxlan`) inherit from `InfraInterface` generic for polymorphic queries 2. **MLAG Domain Model**: MLAG is a domain with exactly 2 devices, plus per-device config (`MlagPeerConfig`) and shared MLAG interfaces (`MlagInterface`) 3. **BGP Hierarchy**: `BGPRouterConfig` → `BGPPeerGroup` → `BGPSession` enables template-based configuration matching Arista EOS structure 4. **EVPN per VLAN**: `EVPNInstance` allows device-specific RD/RT while referencing common `VLAN`/`VNI` ### Mapping to arista-evpn-vxlan-clab | Lab Component | Schema Model | |---------------|--------------| | spine1/2 (AS 65000) | `InfraDevice` + `InfraAutonomousSystem` | | leaf1-8 (AS 65001-65004) | `InfraDevice` + `InfraAutonomousSystem` | | VLAN 40 + VNI 110040 | `InfraVLAN` + `InfraVNI` + `InfraEVPNInstance` | | leaf1+leaf2 MLAG | `InfraMlagDomain` + 2x `InfraMlagPeerConfig` | | Port-Channel999 (peer-link) | `InfraInterfaceLag` | | underlay/evpn peer-groups | `InfraBGPPeerGroup` | ### Next Steps - [ ] Review schema structure - [ ] Test loading into Infrahub dev instance - [ ] Add sample data for validation - [ ] Create Jinja2 transforms (issues #30-33)
Damien moved this to In Progress in Fabric Orchestrator on 2026-02-06 07:47:09 +00:00
Damien added reference feature/41-infrahub-schema 2026-02-06 07:47:27 +00:00
Author
Owner

📋 Schema Refinement Sub-tasks

Audit du schéma réalisé, 7 sous-issues créées pour corriger les faiblesses identifiées :

🔴 Critiques (séquentielles, à traiter en premier)

# Issue Fichier(s) Sévérité
1 #43 — Fix human_friendly_id BGPPeerGroup/BGPSession bgp.yml 🔴 Bloquant
2 #44 — Remove duplicate InterfaceVxlan base.yml, vlan_vxlan.yml 🔴 Bloquant
3 #45 — Add unique on VLAN.vlan_id vlan_vxlan.yml 🔴 Bloquant

🟠🟡 Améliorations (parallélisables après les critiques)

# Issue Fichier(s) Sévérité
4 #46 — Add virtual_router_address + autostate base.yml 🟠 Fonctionnel
5 #47 — Refactor UnderlayLink IPs extensions.yml 🟠 Fonctionnel
6 #48 — Remove Device.router_id + add BGP distances base.yml, bgp.yml 🟠 Fonctionnel
7 #49 — Add trunk_groups + stp_enabled vlan_vxlan.yml 🟡 Mineur

Graphe de dépendances

#43 ──→ #44 ──→ #45 ──→ ┬── #46 (virtual_router_address)
                         ├── #47 (UnderlayLink refactor)
                         ├── #48 (router_id + BGP distance)
                         └── #49 (trunk_groups + STP)

Branche : feature/41-infrahub-schema
Validation à chaque étape : infrahubctl schema check schemas/

## 📋 Schema Refinement Sub-tasks Audit du schéma réalisé, 7 sous-issues créées pour corriger les faiblesses identifiées : ### 🔴 Critiques (séquentielles, à traiter en premier) | # | Issue | Fichier(s) | Sévérité | |---|-------|-----------|----------| | 1 | #43 — Fix human_friendly_id BGPPeerGroup/BGPSession | `bgp.yml` | 🔴 Bloquant | | 2 | #44 — Remove duplicate InterfaceVxlan | `base.yml`, `vlan_vxlan.yml` | 🔴 Bloquant | | 3 | #45 — Add unique on VLAN.vlan_id | `vlan_vxlan.yml` | 🔴 Bloquant | ### 🟠🟡 Améliorations (parallélisables après les critiques) | # | Issue | Fichier(s) | Sévérité | |---|-------|-----------|----------| | 4 | #46 — Add virtual_router_address + autostate | `base.yml` | 🟠 Fonctionnel | | 5 | #47 — Refactor UnderlayLink IPs | `extensions.yml` | 🟠 Fonctionnel | | 6 | #48 — Remove Device.router_id + add BGP distances | `base.yml`, `bgp.yml` | 🟠 Fonctionnel | | 7 | #49 — Add trunk_groups + stp_enabled | `vlan_vxlan.yml` | 🟡 Mineur | ### Graphe de dépendances ``` #43 ──→ #44 ──→ #45 ──→ ┬── #46 (virtual_router_address) ├── #47 (UnderlayLink refactor) ├── #48 (router_id + BGP distance) └── #49 (trunk_groups + STP) ``` Branche : `feature/41-infrahub-schema` Validation à chaque étape : `infrahubctl schema check schemas/`
Damien moved this to Done in Fabric Orchestrator on 2026-02-25 13:59:04 +00:00
Sign in to join this conversation.