Azureネットワーク構成図からaz CLIコマンドでリソース棚卸を自動化する|設計と実態の乖離を検出

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Azure > Azureネットワーク構成図からaz CLIコマンドでリソース棚卸を自動化する|設計と実態の乖離を検出
「Azureのネットワーク構成図を作ったけど、いつの間にか実態と合わなくなってしまった」
そう感じたことはないでしょうか。

Azureの環境は変化が速いです。
VMを追加するたびに、NSGのルールを変えるたびに、azureネットワーク構成図を更新できている現場はほとんどありません。
気づけば図と現実がズレていて、障害対応のときに「この構成図、信用できる?」という状況になります。

この記事では、az CLIを使ってAzureのネットワークリソースを棚卸する手順を解説します。
VNet・サブネット・NSG・NATゲートウェイの実態をコマンドで取得し、設計書(azureネットワーク構成図)との乖離を継続的に検出できるようにします。
この記事では、az CLIがインストール済みのLinux環境(RHEL 9系/Ubuntu 24.04 LTSを想定)を前提とします。

この記事のポイント

・az CLIを使えばAzureの全ネットワークリソースをコマンドで一括棚卸できる
・VNet・サブネット・NSG・NATゲートウェイの実態をJSONで取得して比較できる
・シェルスクリプトで棚卸を自動化すれば構成図との乖離を継続的に検出できる
・孤立NICやNSGの残留ルールなど、設計書にないリソースを発見できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜAzureネットワーク構成図は実態と乖離するのか

Azureの管理ポータルからは手軽にリソースを追加できます。
その手軽さが「あとで構成図を更新しよう」という先送りにつながります。

典型的なケースをいくつか挙げます。

・サブネットの追加やIPアドレスプレフィックスの変更を記録し忘れた
・NSGのルールを「一時的に」緩めたまま本番作業が終わった
・NATゲートウェイの追加をチームに連絡していなかった
・VMを削除したのにNICやパブリックIPが残ったままになっている

こういった変更が積み重なると、ドキュメントと実態の差は広がる一方です。
手作業で確認しようとしても、リソース数が多ければ見落としが起きます。

解決策は「コマンドで棚卸を自動化する」ことです。
az CLIはAzureの全リソースをJSONで取得できます。
シェルスクリプトと組み合わせれば、定期的に実態を記録して差分を検出できます。

az CLIでネットワークリソースを棚卸する準備

1. az CLIのインストールとログインを確認する

まずaz CLIがインストールされているか確認します。

az --version

出力例(環境により異なります):

azure-cli 2.65.0 ... Your CLI is up-to-date.

「...」の部分には拡張機能のバージョンが表示されますが、ここでは省略しています。

ログイン状態の確認は次のコマンドで行います。

az account show --output table

出力例(環境により異なります):

Name CloudName SubscriptionId State IsDefault ------------------ ----------- ------------------------------------ ------- ----------- MySubscription AzureCloud xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Enabled True

SubscriptionIdが表示されていれば、ログイン済みです。
ログインしていない場合は `az login` を実行してください。

2. リソースグループを一覧表示する

棚卸の出発点はリソースグループです。

az group list --output table

出力例(環境により異なります):

Name Location Status ----------------- ------------- --------- rg-web-prod japaneast Succeeded rg-db-prod japaneast Succeeded rg-dev japanwest Succeeded

リソースグループごとに作業を進めると整理しやすいです。
特定のリソースグループだけを対象にするには `--resource-group` オプションを指定します。

VNetとサブネットの実態を取得する

1. VNetの一覧と設定を取得する

サブスクリプション全体のVNetを一覧表示します。

az network vnet list --output table

出力例(環境により異なります):

Name ResourceGroup Location AddressPrefixes ------------- --------------- ---------- ------------------- vnet-prod-01 rg-web-prod japaneast ["10.0.0.0/16"] vnet-dev-01 rg-dev japanwest ["172.16.0.0/16"]

特定のVNetの詳細(サブネット含む)を取得するには次のコマンドを使います。

az network vnet show \ --resource-group rg-web-prod \ --name vnet-prod-01 \ --output json

2. サブネットとアドレスプレフィックスを取得する

VNet内のサブネットを一覧表示します。

az network vnet subnet list \ --resource-group rg-web-prod \ --vnet-name vnet-prod-01 \ --output table

出力例(環境により異なります):

Name AddressPrefix PrivateEndpointNetworkPolicies ----------------- --------------- -------------------------------- snet-web 10.0.1.0/24 Disabled snet-db 10.0.2.0/24 Disabled snet-bastion 10.0.255.0/27 Disabled

ここで取得したAddressPrefixが、azureネットワーク構成図に記載されたアドレス範囲と一致しているか確認します。
一致しない行が「構成図に反映されていない変更」の候補です。

3. VMとNICの接続状況を取得する

VMを削除してもNICが残る「孤立NIC」は、コスト無駄の原因になります。
次のコマンドでリソースグループ内のNICを一覧表示します。

# NICの一覧を取得する az network nic list \ --resource-group rg-web-prod \ --output table

出力例(環境により異なります):

Name ResourceGroup Location MacAddress ProvisioningState ------------- --------------- ---------- ----------------- ------------------- nic-web-01 rg-web-prod japaneast 00-0D-3A-11-22-33 Succeeded nic-web-02 rg-web-prod japaneast 00-0D-3A-44-55-66 Succeeded nic-orphan rg-web-prod japaneast 00-0D-3A-77-88-99 Succeeded

NICに対応するVMが存在するか確認します。

az network nic show \ --resource-group rg-web-prod \ --name nic-orphan \ --query "virtualMachine" \ --output json

出力が `null` であれば、このNICはどのVMにも接続されていない孤立NICです。
孤立NICはazureネットワーク構成図には載っていないことが多いため、発見次第リソース整理を検討します。

NSGとルートテーブルの棚卸

1. NSGの割り当て状況を取得する

NSGの一覧を取得します。

az network nsg list \ --resource-group rg-web-prod \ --output table

特定のNSGに設定されているルールを取得します。

az network nsg rule list \ --resource-group rg-web-prod \ --nsg-name nsg-web \ --output table

出力例(環境により異なります):

Name Protocol DestinationPortRange Access Priority Direction ----------------- ---------- ---------------------- -------- ---------- ----------- AllowSSH Tcp 22 Allow 100 Inbound AllowHTTPS Tcp 443 Allow 200 Inbound AllowHTTP-temp Tcp 80 Allow 300 Inbound DenyAllInbound * * Deny 4096 Inbound

「AllowHTTP-temp」のような「一時的に」追加したルールが残っていることがよくあります。
NSGのルールも棚卸対象に含めることが重要です。

NSGがサブネットとNICのどちらに割り当てられているかも取得します。

# サブネットに割り当てられたNSGを取得する az network vnet subnet list \ --resource-group rg-web-prod \ --vnet-name vnet-prod-01 \ --query "[].{サブネット:name, NSG:networkSecurityGroup.id}" \ --output table

2. ルートテーブルとNATゲートウェイを取得する

カスタムルートテーブルの一覧を取得します。

az network route-table list \ --resource-group rg-web-prod \ --output table

NATゲートウェイの一覧と関連付けられたサブネット数を取得します。

az network nat gateway list \ --resource-group rg-web-prod \ --query "[].{名前:name, サブネット数:length(subnets)}" \ --output table

出力例(環境により異なります):

名前 サブネット数 --------------- ---------- nat-gw-prod 2

サブネット数が0のNATゲートウェイは、どのサブネットにも割り当てられていない状態です。
使われていないNATゲートウェイはコストが発生し続けるため、棚卸で発見したら削除を検討します。

設計と実態の乖離を検出するシェルスクリプト

棚卸結果をファイルに記録しておけば、前回との差分を `diff` で取得できます。
次のスクリプトは、VNet・サブネット・NSGルール・NATゲートウェイ・孤立NICの実態を一括で記録します。

Azureネットワークの設計・構築スキルを体系的に習得したい方は、Azure実践研修(azure.linuxmaster.jp)もご参考ください。

#!/bin/bash # Azure ネットワークリソース棚卸スクリプト # 使い方: bash azure-network-inventory.sh リソースグループ名 VNet名 set -euo pipefail RG="${1:-rg-web-prod}" VNET="${2:-vnet-prod-01}" OUTPUT_DIR="/var/log/azure-inventory" DATE=$(date +%Y%m%d-%H%M%S) mkdir -p "${OUTPUT_DIR}" # サブネット棚卸 az network vnet subnet list \ --resource-group "${RG}" \ --vnet-name "${VNET}" \ --output json > "${OUTPUT_DIR}/subnets-${DATE}.json" echo "[subnets] 保存完了: ${OUTPUT_DIR}/subnets-${DATE}.json" # NSGルール棚卸 az network nsg list \ --resource-group "${RG}" \ --output json > "${OUTPUT_DIR}/nsgs-${DATE}.json" echo "[nsg] 保存完了: ${OUTPUT_DIR}/nsgs-${DATE}.json" # NATゲートウェイ棚卸 az network nat gateway list \ --resource-group "${RG}" \ --output json > "${OUTPUT_DIR}/nat-gateways-${DATE}.json" echo "[nat] 保存完了: ${OUTPUT_DIR}/nat-gateways-${DATE}.json" # 孤立NIC検出 echo "=== 孤立NICの検出 ===" > "${OUTPUT_DIR}/orphan-nics-${DATE}.txt" az network nic list \ --resource-group "${RG}" \ --query "[?virtualMachine == null].name" \ --output tsv >> "${OUTPUT_DIR}/orphan-nics-${DATE}.txt" echo "[orphan-nics] 保存完了: ${OUTPUT_DIR}/orphan-nics-${DATE}.txt" echo "棚卸完了: ${OUTPUT_DIR}"

スクリプトに実行権限を付与して実行します。

chmod +x azure-network-inventory.sh bash azure-network-inventory.sh rg-web-prod vnet-prod-01

出力例(環境により異なります):

[subnets] 保存完了: /var/log/azure-inventory/subnets-20261108-120000.json [nsg] 保存完了: /var/log/azure-inventory/nsgs-20261108-120000.json [nat] 保存完了: /var/log/azure-inventory/nat-gateways-20261108-120000.json [orphan-nics] 保存完了: /var/log/azure-inventory/orphan-nics-20261108-120000.txt 棚卸完了: /var/log/azure-inventory

前回の棚卸結果と比較するには次のように実行します。

# サブネットの差分を取得する diff \ /var/log/azure-inventory/subnets-20261101-120000.json \ /var/log/azure-inventory/subnets-20261108-120000.json

差分が出た箇所が「設計書にない変更」の候補です。
差分が大きい場合は、Azureのアクティビティログと照合して変更の経緯を確認します。

Azureアクティビティログで変更の経緯を追跡する

リソースの変更履歴はアクティビティログで取得できます。

az monitor activity-log list \ --resource-group rg-web-prod \ --start-time 2026-11-01 \ --end-time 2026-11-08 \ --query "[?contains(operationName.value, 'Microsoft.Network')].{時刻:eventTimestamp, 操作:operationName.value, 実行者:caller}" \ --output table

出力例(環境により異なります):

時刻 操作 実行者 ------------------------- ------------------------------------------------------ ----------------------- 2026-11-05T10:23:45+00:00 Microsoft.Network/networkSecurityGroups/write operator@example.com 2026-11-03T14:11:22+00:00 Microsoft.Network/virtualNetworks/subnets/write admin@example.com

「いつ・誰が・何を変更したか」をトレースできます。
構成図を更新するタイミングの判断材料になります。

棚卸スクリプトとアクティビティログを組み合わせると、次のような運用フローで乖離を解消できます。

・棚卸スクリプトを週次でcron実行してJSONを記録する
・前回との差分が出たらアクティビティログで変更者を確認する
・変更内容を構成図に反映してチームに共有する

よくある乖離パターンとトラブルシュート

棚卸を実施すると、次のような乖離が見つかることがよくあります。

・構成図に記載がないサブネットが実環境に追加されている
・「一時対応」として追加したNSGの許可ルールが残り続けている
・削除済みVMに紐付いたNICやパブリックIPが孤立している
・誰も把握していないNATゲートウェイが稼働してコストが発生している

コマンド実行でエラーが出た場合は次を参考にしてください。

「az: command not found」が出た場合

az CLIがインストールされていないか、PATHが通っていません。

# RHEL 9系でのaz CLIインストール(例示) rpm --import https://packages.microsoft.com/keys/microsoft.asc # その後、microsoft.repoを追加してdnf install azure-cli

インストール後は `az --version` でバージョンを確認します。

「CLITokenExpired」またはログインを求められた場合

トークンの有効期限が切れています。
インタラクティブなログインが難しい自動化環境では、サービスプリンシパルを使った認証を設定します。

# サービスプリンシパルで認証する(環境変数を使う方法) export AZURE_CLIENT_ID="アプリID" export AZURE_CLIENT_SECRET="シークレット" export AZURE_TENANT_ID="テナントID" az login --service-principal \ -u "${AZURE_CLIENT_ID}" \ -p "${AZURE_CLIENT_SECRET}" \ --tenant "${AZURE_TENANT_ID}"

サービスプリンシパルのIDや秘密情報はシェルスクリプトに直書きせず、環境変数や外部ファイルから読み込む形にします。

「ResourceGroupNotFound」が出た場合

リソースグループ名のスペルが間違っています。

# 正しいリソースグループ名を取得する az group list --output table

サブスクリプションが複数ある場合は、`az account set --subscription サブスクリプション名` で対象を切り替えてから再実行します。

本記事のまとめ

azureネットワーク構成図と実態の乖離を継続的に検出するために、az CLIによる棚卸手順を解説しました。

やりたいこと コマンド
VNetの一覧を取得する az network vnet list --output table
サブネットの一覧を取得する az network vnet subnet list --resource-group RG --vnet-name VNET --output table
NSGルールの一覧を取得する az network nsg rule list --resource-group RG --nsg-name NSG --output table
孤立NICを検出する az network nic list --resource-group RG --query "[?virtualMachine == null].name" --output tsv
NATゲートウェイの一覧を取得する az network nat gateway list --resource-group RG --output table
ネットワーク変更の履歴を取得する az monitor activity-log list --resource-group RG --start-time YYYY-MM-DD
棚卸スクリプトをcronで定期実行して差分を取得する運用にすれば、azureネットワーク構成図の更新漏れを継続的に検出できます。

構成図は「作ったら終わり」ではなく、「定期的に実態と照合するもの」として扱うことが大切です。

現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、

Azureでのネットワーク設計・VM構築から運用管理まで、実践的なスキルを体系的に習得できます。
詳細はazure.linuxmaster.jpでご確認ください。

>> Azure実践研修の詳細・お申し込みはこちら

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。