netbox-migration について
スプレッドシート、旧式 CMDB、他の IPAM のデータを NetBox に取り込むチーム向けのスキルです。評価と整理からインポート、検証までを案内し、CSV、pynetbox、Diode の選択や依存関係の順序を説明します。
主な機能
- 01移行元の評価とフィールド対応付け
- 02インポート前のデータ整理
- 03CSV、pynetbox、Diode の選択
- 04依存順に沿った段階的インポート
- 05構造、関連、運用状態の検証
活用シーン
- 01スプレッドシートデータの NetBox への取り込み
- 02旧式 CMDB や IPAM からの移行
- 03NetBox 初期データ投入の計画
- 04複数ソースのインフラ記録の統合
MCP 対応
設定済みの NetBox MCP サーバーを使い、移行データが正しく取り込まれたか確認できると説明します。このスキル自体は MCP サービスを提供しません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ netboxlabs/ skills --skill netbox-migrationインストール後、Claude Code で/netbox-migrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/dependency-order.mdimport-patterns.mdsource-mapping.mdvalidation-checklist.md詳細
NetBox の移行
NetBox のインポート方法に関する知識は古くなっている可能性があります。 利用可能なインポート方法、一括操作の上限、Diode のエンティティタイプはリリースごとに変化します。事前学習済みの知識ではなく、情報を取得して確認してください。
情報の取得元
| 取得元 | URL/方法 | 用途 |
|---|---|---|
| NetBox REST API のドキュメント | https://netboxlabs.com/docs/netbox/integrations/rest-api/ | 一括作成/更新エンドポイント |
| Diode のドキュメント | https://netboxlabs.com/docs/diode/ | 大量データの取り込み |
| pynetbox リポジトリ | https://github.com/netbox-community/pynetbox | スクリプトによるインポート用 Python SDK |
| NetBox MCP サーバー | 設定されている場合 — インポートしたデータが正しく取り込まれたことを確認 | 移行後の検証 |
このスキルでは、NetBox へのデータ移行について、考え方と実行方法を説明します。乱雑なソースデータの分析、クリーニング、インポート戦略の選択、適切な順序での読み込み、すべてが正しく取り込まれたことの検証まで、全工程を網羅します。
NetBox のバージョンアップについての説明ではありません。 スプレッドシート、レガシーツール、その他の CMDB のデータを、初めて NetBox に取り込む(または再インポートする)ための説明です。
このスキルを使う場面
- NetBox にインポートするスプレッドシート、CSV、データダンプを受け取った場合
- 別の CMDB/IPAM(phpIPAM、Device42、RackTables、ServiceNow、InfoBlox)から移行する場合
- NetBox のデプロイを計画しており、初期データの投入が必要な場合
- 複数のソースのデータを統合し、NetBox を信頼できる情報源にする場合
クイックスタート判断ツリー
データ量はどのくらいですか?
- オブジェクト数が 100 未満 → NetBox の CSV インポート UI
- オブジェクト数が 100~10K → pynetbox スクリプト
- オブジェクト数が 10K 以上、または継続的な同期 → Diode SDK
ソースは何ですか?
- スプレッドシート → まずクリーニングし、その後 pynetbox または CSV インポートを使用
- レガシー IPAM ツール → 既存の移行ツールを確認し、なければエクスポート→変換→インポート
- ネットワーク検出データ → 基本データをインポートし、その後 Discovery で拡充
- 複数のソース → データタイプごとに主要なソースを決め、競合を調整
一度限りですか、それとも継続的ですか?
- 一度限り → get-or-create パターンを使った pynetbox スクリプト
- 継続的な同期 → スケジュール実行する Diode SDK
- ハイブリッド → 一括処理には Diode を使い、リレーションの修正には pynetbox を使う
5 つのフェーズ
すべての移行はこの流れに沿って進みます。フェーズを省略しないでください。最もよくある失敗は、評価とクリーニングをせずにインポートへ直行することです。
フェーズ 1:評価
目標: 現状、NetBox が必要とするもの、そして両者のギャップを把握します。
-
データソースを棚卸しする — インフラストラクチャのデータが含まれるすべてのスプレッドシート、データベース、ツール、Wiki ページ、担当者の記憶をリストアップします。データの種類ごとに、どのソースが正式な情報源なのかを特定します。
-
フィールドを NetBox のモデルに対応付ける — 各ソースのフィールドについて、対応する NetBox のモデルとフィールドを特定します。ソースシステムごとの一般的な対応付けについては、references/source-mapping.md を参照してください。
-
残すものと引き継がないものを決める — すべてのデータを移行するわけではありません。NetBox には固有のモデルがあり、適合しないデータはカスタムフィールドやコメントに格納するか、破棄します。原則は、スプレッドシートにあるものではなく、NetBox が必要とするものから始めることです。
-
対象範囲を決める — フェーズを分けて移行します。まず物理階層(サイト、ラック、デバイス)から始め、次に IPAM、接続、そしてデータの拡充へと進みます。一度にすべてを行おうとしないでください。
-
既存のツールを確認する — phpIPAM には
ipam-migrator、RackTables にはracktables2netboxがあります。カスタムスクリプトを書く前に、GitHub を検索してください。
注意が必要な対応付け:
- ソースの「Location」は、NetBox ではサイト、サイト内のロケーション、またはリージョンを意味する場合があります
- ソースの「Device type」は通常ロールを意味し、ハードウェアモデルを表す NetBox の DeviceType ではありません
- ソースにデバイスごとに 1 つの IP しかない場合 → Interface を作成し、IP を割り当ててから、primary_ip に設定する必要があります
- 「Cisco Catalyst 9300-48P」→ Manufacturer("Cisco")と DeviceType(model="Catalyst 9300-48P")に分割します
- ロケーション階層「Building A, Floor 3, Room 301」→ Location オブジェクトをネストします
NetBox のデータモデルと関係については、netbox-data-modeling を参照してください。
フェーズ 2:データのクレンジング
原則: ゴミを入れれば、ゴミが出てきます。インポートする前にクレンジングしてください。インポート後に NetBox でデータを修正するより、スプレッドシートで修正するほうが簡単です。
クレンジング作業トップ 10:
-
名前を正規化する — 命名規則(小文字とハイフンの使用を推奨)を決め、すべてに適用します。「NYC-DC1」、「New York DC 1」、「nyc dc1」→
nyc-dc1。 -
メーカー名を統一する — 「Cisco」、「cisco」、「Cisco Systems」、「CISCO」→ 正式名称を 1 つに統一します。大文字と小文字の区別は重要です。特に Diode のリコンサイラーでは重要です。
-
デバイスタイプを統一する — 「C9300-48P」、「Catalyst 9300 48P」、「WS-C9300-48P」→ ハードウェアモデルごとにモデル文字列を 1 つに統一します。
-
重複を排除する — ソースによって異なる名前が付いている同一デバイスや、複数のレコードに記載された同一 IP を確認します。正式なレコードを選びます。
-
古いデータを削除する — 何年も前に廃止されたデバイスが、まだスプレッドシートに残っていることがあります。
decommissioningとしてマークするか、削除します。 -
IP を検証する — 正しい CIDR 表記である必要があります。ホストアドレスには
/32を追加します。10.0.0.1/24は /24 上の IP アドレスであり、プレフィックスではありません。その違いを把握してください。 -
必須フィールドを入力する — すべての Device に必要なものは、
name、device_type、role、siteです。すべての IP には CIDR 形式のaddressが必要です。モデルごとに NetBox の必須フィールドを確認してください。 -
ステータス値を対応付ける — ソースの「production」/「live」/「up」→ NetBox の
active。ソースの「down」/「retired」→ NetBox のofflineまたはdecommissioning。有効な選択肢は、active、planned、staged、offline、decommissioning、inventory です。 -
複数の値を含むセルを処理する — 1 つのセルにある「10.0.1.1, 10.0.1.2」→ 個別のレコードに分割します。
-
書式設定による不要な要素を取り除く — Excel による先頭のゼロの削除、末尾のスペース、BOM 文字、空白を生むセルの結合、「N/A」や「unknown」の値などについて、スキップするかプレースホルダーを使うかを決めます。
コミュニティでの知見: 「NetBox に少数のレコードを手動で入力してエクスポートし、その形式に合わせて CSV を作成します。」NetBox の CSV エクスポートのヘッダーはインポートのヘッダーと一致しません。まず少量のサンプルで必ずテストしてください。
フェーズ 3:インポート
references/import-patterns.mdの判断フレームワークに基づいて、適切な方法を選択してください。
| 方法 | 最適な用途 | 依存関係の順序 |
|---|---|---|
| CSV インポート(UI) | 1,000 オブジェクト未満、シンプルな型 | 手動 — 一度に 1 つの型 |
| pynetbox | 1,000~100,000 件、複雑なロジック | 手動 — 順序を自分で制御 |
| Diode SDK | 10,000 件以上、継続的な同期 | 自動 — リコンサイラーが依存関係を処理 |
| カスタムスクリプト | パターン化されたデータ、NetBox 内での変換 | 手動 — Django ORM |
方法にかかわらず、依存関係の順序を守ってください。 オブジェクトがほかのオブジェクトから参照される前に、作成されている必要があります。全 11 階層の順序については、references/dependency-order.mdを参照してください。
依存関係の階層の概要:
- テナント、タグ、メーカー、RIR、デバイスロール、ラックロール
- リージョン、サイトグループ
- サイト
- ロケーション(サイト内)
- ラック(ロケーション内)— (4.7) 次に冷却ソース/フィード
- デバイスタイプ+コンポーネントテンプレート(メーカーが必要)— (4.7) 使用する場合はモジュールベイタイプを先に作成
- デバイス(タイプ、ロール、サイトが必要)— コンポーネントはテンプレートから自動作成
- インターフェイス(テンプレートにないカスタムのもの)— (4.7) チャネルサブインターフェイスは親の後に作成
- VRF、VLAN、プレフィックス、IP アドレス → インターフェイスに割り当て、サービス
- ケーブル、回線、プロバイダー
- 仮想マシン、クラスター、コンフィグコンテキスト、カスタムフィールド値
循環依存の問題: デバイスのprimary_ipを設定するには、デバイスを作成 → インターフェイスを作成(テンプレートから自動作成)→ IP を作成 → IP をインターフェイスに割り当て → デバイスのprimary_ipを更新、という手順が必要です。そのため、2 回に分けて処理します。まずすべてを作成し、その後でプライマリ IP を設定します。
Diode を使えば、順序に関する懸念の大半が解消されます。 不足している依存関係は自動的に作成されます。存在しないサイトを参照するデバイスを取り込むと、Diode が先にサイトを作成します。大規模な移行では、これは大きな利点です。netbox-diodeを参照してください。
インポートの主なルール:
- 常に get-or-create パターンを使用する — スクリプトをべき等にし、再実行可能にします
- 最初にステージング環境でテストする — ドライランには別の NetBox インスタンスを使用します
- フェーズごとにインポートする — まずサイト/ラックをインポートして確認し、次にデバイスをインポートして確認し、その後 IPAM をインポートします
- CSV ではデータベース ID ではなく、名前/slug でオブジェクトを参照する
- DeviceType/ModuleType には CSV ではなく YAML 形式を使用する(コンポーネントテンプレートが含まれるため)
- pynetbox で一括作成する:
nb.dcim.devices.create([{...}, {...}])— スループット/メモリのための推奨サイズであり、NetBox が強制する上限ではない約 100 件ずつのチャンクで処理します。一括書き込みは全件成功または全件失敗です。(4.7) 一括書き込みに失敗すると、問題のあるオブジェクトごとに、送信したリスト内のindexを含むエラーが返されます。これを元の行に対応付け、該当するものだけを再送信してください。非常に大きなバッチは、?background=trueを付けてバックグラウンドジョブとして実行できます。references/import-patterns.mdを参照してください。 - デバイス/VM の読み取りでは、
?omit=config_contextを使ってconfig_contextを除外する(4.5.2 以降):4.5~4.6ではオブジェクトごとの大規模なレンダリングを省略し、4.7.0~4.7.2ではコンフィグコンテキストがキャッシュされているためペイロードだけを削減します。4.7.3 以降では(?fields=/?brief=Trueと同様に)DB アノテーションを再び省略します。?exclude=config_contextは 4.5~4.6 では同等ですが、4.7.x ではすべて無視されます。 - 検証のために大量のデータを読み戻す場合: NetBox 4.6 以降では、深い
?offset=スキャンよりもカーソルページネーション(?start=<id>&limit=N)を優先してください。大きなオフセットでは、オフセットによる処理が線形に遅くなります。netbox-api-integrationを参照してください。
API の使用パターンについては、netbox-api-integrationを参照してください。
フェーズ 4:検証
検証は 3 層すべてが必要です。移行を完了するには、3 層すべてを実施してください。
レイヤー 1:構造(NetBox が受け入れた)
- オブジェクト数が移行元と一致する:デバイス、IP、プレフィックス、サイト、VLAN
- インポートエラーやスキップされたレコードがない
- すべてのオブジェクトに必須フィールドが入力されている
- カスタムフィールドの値が反映されている — (4.7) 選択/複数選択の値は
{"value", "label"}オブジェクトとして読み戻されます。["value"]と比較し、生の値を書き込みます
レイヤー 2:リレーション(接続が正しい)
- すべてのデバイスのサイト、デバイスタイプ、メーカー、ロールが正しい
- すべての IP が、正しいデバイス上の正しいインターフェースに割り当てられている
- プライマリ IP を設定する必要があるデバイスに、プライマリ IP が設定されている
- ラックの位置が移行元のレイアウトと一致している
- VLAN とプレフィックスの関連付けが正しい
- VRF の割り当てがルーティング設計と一致している
- プレフィックスの階層が妥当である(コンテナに子プレフィックスが含まれている)
レイヤー 3:運用(稼働中のネットワークと一致)
- NetBox に登録されたデバイスがネットワーク上で応答する
- NetBox の IP が実際のデバイス設定と一致する
- ネットワーク上に存在するのに NetBox に登録されていないデバイスがない
- インターフェースの状態が実際の状態と一致する
- このレイヤーではディスカバリーとアシュアランスを使用します — フェーズ 5 を参照してください
完全なチェックリストについては、references/validation-checklist.md を参照してください。
検証スクリプトのパターン:
import pynetbox
nb = pynetbox.api("https://netbox.example.com", token="...")
# Count verification
source_device_count = 500 # from your source data
assert nb.dcim.devices.count() >= source_device_count
# Spot-check critical devices
for name in ["core-rtr-01", "fw-01", "dns-01"]:
d = nb.dcim.devices.get(name=name)
assert d, f"Missing: {name}"
assert d.primary_ip, f"No primary IP: {name}"
assert d.site, f"No site: {name}"
# Find orphaned IPs
for ip in nb.ipam.ip_addresses.all():
if not ip.assigned_object:
print(f"Unassigned: {ip.address}")
フェーズ 5:移行後
データを読み込んだだけでは、移行は完了しません。 NetBox が実態と一致し、信頼できる唯一の情報源として確立されたときに完了します。
ディスカバリーを実行して不足分を補う
スプレッドシートにすべての情報が含まれていることはありません。Orb Agent を使って不足情報を検出します。
- ネットワークスキャン(NMAP) — NetBox に登録されていない IP を見つけ、不正なデバイスを特定します
- デバイスディスカバリー(NAPALM/SNMP) — 実際のインターフェース設定、VLAN、MAC アドレス、OS バージョンを取得します
- LLDP/CDP の隣接データ — ケーブル接続を自動的に検出します
ディスカバリーによって、移行元データに常に不足している情報を補います。インターフェース、実際の IP 割り当て、MAC アドレス、実際のプラットフォームバージョン、ケーブル配線トポロジーなどです。netbox-discovery を参照してください。
アシュアランスを実行して正確性を確認する
「正しい」状態をルールとして定義し、準拠状況を確認します。
- 稼働中のすべてのデバイスにプライマリ IP が設定されている
- 稼働中のすべてのデバイスに、少なくとも 1 つのインターフェースがある
- すべてのラックにサイトとロケーションが設定されている
- すべてのプレフィックスに VRF が設定されている(複数 VRF の環境の場合)
- 同じ VRF 内に重複した IP がない
netbox-assurance を参照してください。
継続的なプロセスを確立する
- ドリフトを検出するため、ディスカバリーを定期的に実行するようスケジュールします
- アシュアランスレポートを毎週確認します
- 変更プロセスを確立します。変更はまず NetBox に反映し、その後ネットワークに実装します
- 自動化と統合します(Ansible/Terraform が信頼できる唯一の情報源として NetBox から情報を取得します)
完了基準
次の条件を満たしたとき、移行は完了です。
- ✅ 移行元のすべてのデータが NetBox に登録されている(すべてのデバイス、IP、プレフィックス、VLAN)
- ✅ リレーションが正しい(IP → インターフェース → デバイス → ラック → サイト)
- ✅ 階層が構造化されている(リージョン → サイト → ロケーション → ラック)
- ✅ IPAM が整理されている(プレフィックス階層、VRF のスコープ設定、集約がすべてのアドレス空間を網羅)
- ✅ 命名規則に一貫性がある(規則が統一され、重複や曖昧さがない)
- ✅ ディスカバリーにより実態との一致が確認されている(実在しないデバイスも、未登録のデバイスもない)
- ✅ アシュアランスルールに合格している(コンプライアンスチェックがすべて合格)
- ✅ 移行元システムを廃止できる(NetBox が正式な情報源になっている)
アンチパターン
- エクスポート形式 ≠ インポート形式 — NetBox の CSV エクスポートのヘッダーは、インポートのヘッダーとは異なります。必ずサンプルでテストしてください。
- 大文字と小文字の区別 — 「Site A」と「site a」は、特に Diode 経由の場合、重複して作成されます。
- インターフェースは自動作成される — DeviceType テンプレートは、デバイスの作成時にインターフェースを作成します。再作成しないでください。
- 循環依存関係(プライマリ IP) — 2 段階で行う必要があります。デバイスを作成 → IP を作成 → デバイスに割り当てます。
- CSV のエンコーディング — BOM なしの UTF-8 と LF 改行を使用してください。
- スラッグの競合 — 自動生成されたスラッグが競合する場合があります。名前が似ている場合は、明示的にスラッグを指定してください。
- デバイス名の一意性 — 一意性はサイトとテナントごとであり、全体ではありません。異なるサイトで同じ名前を使用しても問題ありません。
- 大規模な CSV インポートは遅い — オブジェクトが 1K を超える場合は、API または Diode に切り替えてください。
- すべてを一度に移行しない — 段階的に進めてください。サイト → デバイス → IPAM → 接続。
- 「圧倒されていると感じる」 — それは普通です。NetBox にモデルがあるものに集中してください。対応するモデルがないデータは無視してください。
バージョンに関する注意事項
NetBox 4.7 (2026-09-02)
- 一括作成/更新に失敗すると
{"detail", "errors": [{"index": N, "errors": {...}}]}が返されます(引き続き全件成功または全件失敗です)。一括書き込みで?background=trueを指定すると、202 とポーリングするジョブが返されます。references/import-patterns.md を参照してください。 ?exclude=config_contextは 4.7.x のすべてのバージョンで黙って無視されます(config context はキャッシュされます)。代わりに?omit=config_contextまたは?fields=を使用してください。4.7.0~4.7.2 ではペイロードのみ、4.7.3 以降では DB アノテーションも再び省略されます。- 選択式カスタムフィールドは
{"value", "label"}として読み込まれます。書き込みでは従来どおり生の値も受け付けます。 - サービスでは、
protocolとportsに代わってport_mappings(["tcp/443"])を使用します(従来の 2 つの項目も書き込み可能ですが、5.0 で削除されます)。 - インポート可能なモデルが追加されました。
ModuleBayType、冷却ソース/供給口/吸気口/排気口、チャネルのサブインターフェース、および DeviceType/ModuleType のend_of_lifeとcooling_methodです。references/dependency-order.md と references/source-mapping.md を参照してください。 - 階層は
ltreeに移行しました。REST の_depthに変更はありませんが、NetBox 内のスクリプトではlevelによるフィルタリングや並べ替えができなくなりました。 - コアのカスタムスクリプトは非推奨です(5.0 で削除)。新しいインポートツールには pynetbox/Diode を推奨します。
NetBox 4.6 (2026-06-04)
- カーソルページネーション(
?start=)、書き込み専用のadd_tags/remove_tags、RackGroup、CableBundle、VirtualMachineType。
参考資料
- references/source-mapping.md — ソースシステムごとのフィールドマッピング
- references/dependency-order.md — 全 11 階層のインポート順序
- references/validation-checklist.md — インポート後の検証チェックリスト
- references/import-patterns.md — 各インポート方法のコード例