netbox-migration
Modularer, dreistufiger NetBox-Import für die RZ-Erstmigration. Nimmt die
*_v4.json Consolidated-Payloads aus dem Gather (serverfacts_v4), sortiert sie
nach Typ und importiert sie in Abhängigkeitsreihenfolge nach NetBox.
Warum drei Ordner + drei Pässe?
Der erste Migrationslauf hat alles als Bare-Metal angelegt. Jetzt trennen wir
sauber auf — und weil is_virtual/pve_version nur aus einer dmidecode-Heuristik
kommen, sind Fehlklassifizierungen erwartbar. Die drei Ordner geben dir einen
Human-in-the-Loop-Checkpoint: zwischen den Pässen kannst du eine falsch
einsortierte JSON per Hand in den richtigen Ordner schieben.
Reihenfolge ist zwingend:
- Pass 1 — PVE legt Cluster + Hypervisor an. Muss zuerst laufen, denn …
- Pass 2 — VMs hängen die VMs an den in Pass 1 erzeugten Cluster (mit
konditionalem Cleanup: ein fälschlich angelegtes physisches Device gleichen
Namens wird entfernt — aber nur, wenn es real existiert). - Pass 3 — Bare-Metal importiert den Rest (spiegelbildlicher Cleanup einer
fälschlich angelegten VM).
Struktur
netbox-migration/
├── ansible.cfg
├── inventory.ini
├── group_vars/all.yml # ← hier alles konfigurieren (URL, Token, Site, Flags)
├── site.yml # Orchestrator (alle 3 Pässe)
├── 01_import_pve.yml # Pass 1
├── 02_import_vms.yml # Pass 2
├── 03_import_bare_metal.yml # Pass 3
├── query_inventory.yml # Bestandsreport (Pre-/Post-Flight)
├── scripts/classify_nodes.py # sortiert inventar/*_v4.json -> Unterordner
├── roles/netbox_import/
│ ├── defaults/main.yml
│ └── tasks/
│ ├── pve.yml # 1 PVE-Node verarbeiten
│ ├── vm.yml # 1 VM verarbeiten (+ Cleanup)
│ ├── bare_metal.yml # 1 phys. Server verarbeiten (+ Cleanup)
│ ├── _scaffold_device.yml# Manufacturer/Type/Role (geteilt)
│ └── _interfaces.yml # Interfaces/MAC/IP + primary_ip4 (Device & VM)
├── credentials/ # gitignored — netbox_api_token hier ablegen
│ └── netbox_api_token.sample
└── inventar/
├── *.sample_v4.json # eingecheckte Demodaten
├── 1_pve_cluster/
├── 2_vms/
└── 3_bare_metal/
Voraussetzungen
netbox.netboxCollection +pynetboxin der venv (nutzt../.venvdes
Root-Repos — Pfad ingroup_vars/all.ymlanpassen, falls anders).- NetBox 4.2+ (das MAC-Objektmodell in
_interfaces.ymlbraucht ≥ 4.2). - API-Token nach
credentials/netbox_api_tokenlegen (ohne.sample).
Ablauf
cp credentials/netbox_api_token.sample credentials/netbox_api_token # echten Token eintragen
# group_vars/all.yml prüfen: netbox_url, netbox_site, netbox_validate_certs
# 0) JSONs sortieren (Quelle: inventar/)
python3 scripts/classify_nodes.py # --move zum Verschieben
# -> danach die drei Ordner kurz durchsehen und ggf. von Hand korrigieren
# 1) Bestand VOR dem Import festhalten
ansible-playbook query_inventory.yml
# 2) Pass für Pass (beim ersten Mal einzeln, dazwischen prüfen)
ansible-playbook 01_import_pve.yml
ansible-playbook 02_import_vms.yml
ansible-playbook 03_import_bare_metal.yml
# ... oder alles am Stück: ansible-playbook site.yml
# 3) Verifizieren
ansible-playbook query_inventory.yml # netbox_inventory_report.md
Overrides jederzeit per -e, z. B.:
ansible-playbook 01_import_pve.yml -e netbox_url=https://inv.test.net -e cleanup_wrong_type=false
Zur netbox_id
Ein separates Vorab-Abfragen der ID pro Host ist nicht nötig — die
netbox.netbox-Module lösen idempotent über den natürlichen Schlüssel auf
(name+site beim Device, name+cluster bei der VM) und geben das Objekt
inkl. .id zurück (siehe primary_ip4-Zuweisung in _interfaces.yml).
Explizite ID-Abfragen (via uri) nutzen wir nur für den konditionalen
Cleanup und den Report — dort brauchen wir die Existenz/ID wirklich.
Bessere Cluster-Zuordnung (optional, empfohlen)
Der Clustername wird sonst aus dem FQDN geraten (pve01.testcluster1... →
testcluster1). Verlässlicher ist die PVE-API als Autorität:
GET /api2/json/cluster/resources?type=vm liefert die echte VM↔Node-Zugehörigkeit.
Für einen festen Namen: -e netbox_cluster_name=testcluster1.