NSXのオーバーレイネットワーク、分散ファイアウォール(DFW)、DHCPなどの基盤構築が完了しました。
本来なら次はロードバランサ(Avi Load Balancer)の構築に進む予定でしたが、設定が増えてくるにつれて「ある悩み」が出てきました。
「NSXの設定全体を、もっと見やすく一覧化したい…!」
NSX ManagerのGUIは優秀ですが、ファイアウォールのルールが数百行に及んだり、多数のオブジェクト(グループやサービス)が入り組んでくると、「全体としてどうなっているか」を把握するのが辛くなってきます。画面キャプチャでドキュメントを残すのも限界がありますし、何より「昨日と今日で何が変わったか(Diff)」を取るのが困難です。
そこで今回は、Pythonを使ってNSXのAPIを叩き、設定情報を取得して「見やすいHTMLレポート」を自動生成するツールを作成しました。
これが想像以上に便利で、「構成管理」や「移行時の現状調査」にも使える強力なツールになったので、コードのポイントと共に紹介します。
作ったものの概要
今回作成したツール(NSXFW_Report.py)の仕組みは以下の通りです。
ファイル
| ファイル名 | 内容 |
|---|---|
| NSX-T Firewall Report Generator_12.2.0.py | スクリプト本体 |
| nsx_raw_data_debug_20251223_232101.json | APIで取得したJSONファイルのサンプル |
| NSXFW_HomeLab_20251223_232101.html | 取得したJSONファイルをもとに生成したHTMLファイル |
以下に公開しているので、自由にご利用ください。
NSX_HTML化 - Google ドライブ
使い方
Pythonのインストール
事前にPythonのインストールを行ってください。
GUIでインストールする際には、Pathを通しておいてください。
その後、pip install requests を実行してください(最初の1回だけでOK)
アカウント・環境情報の設定
スクリプトの冒頭で、アカウント・環境情報の設定をしてください。
私の環境では、このように設定しています。
NSX_MANAGER_URL = "https://nsx21.lab.local" USERNAME = "admin" PASSWORD = "VMwarevmware1!"
Pythonの実行
スクリプト本体をダブルクリックするか、コマンドプロンプトから実行してください。
正常終了すれば、最後に「処理完了: ファイルを出力しました」と表示され、スクリプト本体と同じフォルダにHTMLファイルが出力されます。
また、取得した情報もJSONで出力します。
もし、この情報が不要であれば、デバッグ設定で、DEBUG_MODE = False としてください。
うまく動作しないときは、スクリプトとJSONファイルをAIに読み込ませると、いい感じに修正してくれると思います。
PS C:\work\01_HTML化> python .\NSXFW_Report_v11.1.py [2025-12-23 23:00:14] [INFO] === NSX-T Firewall Report Generator v11.3.0 (Fix: CIDR & Dups) === [2025-12-23 23:00:14] [INFO] Env: NSX-T Report: Home Lab (On-Prem) [2025-12-23 23:00:14] [INFO] NSX-T APIへの接続を開始します... [2025-12-23 23:00:14] [INFO] tier-1s の一覧を取得中: https://nsx21.lab.local/policy/api/v1/infra/tier-1s [2025-12-23 23:00:14] [INFO] -> 1 個の tier-1s が見つかりました。 [2025-12-23 23:00:14] [INFO] tier-0s の一覧を取得中: https://nsx21.lab.local/policy/api/v1/infra/tier-0s [2025-12-23 23:00:14] [INFO] -> 1 個の tier-0s が見つかりました。 [2025-12-23 23:00:14] [INFO] GW FW処理中: T0-GW-01 (tier-0s)... [2025-12-23 23:00:14] [INFO] GW FW処理中: T1-GW-01 (tier-1s)... [2025-12-23 23:00:14] [INFO] 共通リソース取得中: Default Domain Groups ... [2025-12-23 23:00:14] [INFO] -> 成功: 11 件のグループ定義 [2025-12-23 23:00:14] [INFO] 共通リソース取得中: Services ... [2025-12-23 23:00:14] [INFO] -> 成功: 415 件のサービス定義 [2025-12-23 23:00:14] [INFO] 共通リソース取得中: Global Segments ... [2025-12-23 23:00:14] [INFO] -> 成功: 2 件のセグメント定義 [2025-12-23 23:00:14] [INFO] ★デバッグ用JSONファイルを出力しました: nsx_raw_data_debug_20251223_230014.json [2025-12-23 23:00:14] [INFO] HTMLレポートの生成を開始します... [2025-12-23 23:00:14] [INFO] -> ページ構築中... [2025-12-23 23:00:14] [INFO] 処理完了: ファイルを出力しました -> NSXFW_HomeLab_20251223_230014.html [2025-12-23 23:00:14] [INFO] 総取得ルール数: 5 件 [2025-12-23 23:00:14] [INFO] 出力先: C:\work\01_HTML化\NSXFW_HomeLab_20251223_230014.html 処理が完了しました。Enter キーを押して終了してください... PS C:\work\01_HTML化>
生成されるHTMLレポート(イメージ)
実際にホームラボ環境から生成したHTMLがこちらです。 ネイティブのGUIよりも情報が凝縮されており、検索もテキストコピーも容易です。

このツールのメリット
単に表示するだけならGUIでも良いのですが、HTML化(テキスト化)することで以下のメリットが生まれます。
- 「差分(Diff)」が取れる
HTML(テキスト)なので、設定変更前と後でスクリプトを実行し、WinMerge や diff コマンドにかければ、「どのルールが追加・削除されたか」が一発で分かります。これはGUIでは不可能です。
- オフラインで閲覧可能
HTMLファイル単体で動作するため、NSX Managerにアクセスできない環境でも設定内容を確認できます。客先への納品ドキュメントとしても使えます。
- 生データ(JSON)も手に入る
デバッグモードで実行すれば、加工前のRaw JSONデータも出力されます。これは将来的な**移行(Migration)**や、バックアップデータとしても非常に有用です。
コードの解説(要点)
スクリプト全体は長くなるので、ロジックの要点をピックアップして解説します。
NSX APIへの接続とデータ取得
requests ライブラリを使用して、NSX ManagerのPolicy APIへアクセスします。 認証はBasic認証を使用し、SSL証明書検証はラボ環境なのでスキップしています。
# APIクライアントの一部抜粋 class NSXClient: def get(self, endpoint): url = f"https://{self.nsx_manager}{endpoint}" response = requests.get( url, auth=(self.username, self.password), verify=False # ラボ用: 証明書検証無効 ) return response.json() # 取得する情報の例 endpoints = { "groups": "/policy/api/v1/infra/domains/default/groups", "services": "/policy/api/v1/infra/services", "dfw_policies": "/policy/api/v1/infra/domains/default/security-policies", # ... その他、GW FWやSegmentsなど }
「パス」から「名前」への変換(名前解決)
APIから返ってくるデータは、基本的に /infra/domains/default/groups/web-group のような「パス」で表現されています。 これを人間が見やすい「グループ名(例: Web-Servers)」に変換する処理を入れています。これがないと、レポートがパスだらけで読みにくくなってしまいます。
# パスと表示名のマッピング辞書を作成 self.path_to_name = {} for group in groups_data.get('results', []): self.path_to_name[group['path']] = group['display_name'] # 実際の変換ロジック(例) def resolve_name(path): return self.path_to_name.get(path, path) # 名前があれば名前を、なければパスをそのまま返す
HTMLへのレンダリング(Jinja2)
データの整形が終わったら、Pythonのテンプレートエンジンである Jinja2 を使ってHTML化します。 CSSもHTML内に埋め込んでいるため、単一のファイルとして完結するようにしています。
# テンプレートにデータを渡してレンダリング template = Template(html_template_string) html_output = template.render( timestamp=timestamp, nsx_manager=args.nsx_manager, dfw_policies=processed_data['dfw_policies'], # ... 他のデータを渡す )
実際の出力結果
スクリプトを実行すると、以下のようにセクションごとに整理された情報が出力されます。
- 分散ファイアウォール (DFW)
「Source」「Destination」「Service」「Action」が一覧化されています。 特にグループの中身(IPアドレスやタグ条件)も、別セクションの「Groups」と突き合わせることで容易に確認できます。
| ID | Name | Source | Destination | Service | Action |
|---|---|---|---|---|---|
| 1020 | Allow Web to DB | Grp-Web | Grp-DB | PostgreSQL | ALLOW |
| 1021 | Block Any | Any | Any | Any | DROP |
- グループ定義 (Inventory Groups)
どのグループに、どんなIPアドレスやタグが紐付いているかも一目瞭然です。
| Group Name | Criteria / Members |
|---|---|
| Grp-Web | Tag: Web-Tier |
| Grp-DB | Tag: DB-Tier |