昨今、AI を活用したインシデント対応の自動化が注目されています。たとえば、Microsoft では、チケットの自動解決、自動トリアージ、レポートの自動生成などを通して、インシデント対応の効率化を図っています。こうした取り組みは、AIOps (Artificial Intelligence for IT Operations) と呼ばれ、学術/産業界で活発に議論と応用が進められています。
本来、AI の活用には、機械学習モデルのトレーニングやデータの収集・分析など、非常に多くの準備と手間が必要です。しかし、事前学習済みで推論能力に優れる言語モデル (LLM/エージェント) が登場したことで、より手軽に AI を試すことができるようになりました。特に、エージェントが外部のツールを呼び出せるようになる仕組み (Model Context Protocol; MCP) が整備され、よりいっそう外部連携も手軽になっています。
本記事では、Azure のリソースを操作するための MCP ツール (Azure MCP Server) を活用して、Azure 上のインシデント対応を効率化する方法を紹介します。
Azure MCP Server とは何か
Azure MCP Server は、Azure リソースに対する操作 (Azure Resource Manager に対する REST API 呼び出し) を実行するための MCP サーバーです。
たとえば、次のような操作を実行できるツールが用意されています (一覧)
- Cosmos DB のデータを取得する
- Azure Storage の Blob を操作する
- Azure SQL Database のクエリを実行する
ツールとして用意されていない操作も多々ありますが、その場合は azmcp-extension-az
ツールで代用できます。このツールは、Azure CLI のコマンドを MCP Server 経由で実行するためのものです。ただし、コマンドの引数などを記述する能力は LLM/エージェント依存となるため、実行エラーが発生する可能性があります。エラーを軽減するには、あらかじめコマンドのサンプルを用意しておくことをお勧めします。
インシデント対応の文脈で使用できそうなツールを抜粋すれば、次のようなものがあります。
ツール | 説明 | 使える場面 |
---|---|---|
azmcp-extension-az |
Azure CLI のコマンドを実行する | MCP Server でサポートされていない操作を実行する (例: プラットフォーム メトリックの取得) |
azmcp-kusto-query |
Azure Data Explorer のクエリを実行する | Data Explorer に保存されたログを取得する |
azmcp-log-query |
Log Analytics ワークスペースのクエリを実行する | Log Analytics に保存されたログを取得する |
今回の自動インシデント対応では、azmcp-log-query
ツールを使用して Log Analytics ワークスペースに保存されたログを取得し、トラブルシューティング ガイドに従って問題の原因を調査します。
認証方式
REST API を呼び出すため、Azure MCP Server は Entra ID トークンを必要とします。Azure MCP Server は様々な方法でトークンを取得できますが、次のような認証方式が代表的なものになるかなと思います。
-
環境変数: 環境変数 (
AZURE_CLIENT_ID
,AZURE_TENANT_ID
,AZURE_CLIENT_SECRET
) を参照する方式。CI/CD パイプラインなど、サーバー上で MCP サーバーを実行する場合に使用される。(参考) - Managed Identity: Azure リソースに割り当てられた Managed Identity を使用する方式。Azure VM や App Service など、Azure リソース上で MCP サーバーを実行する場合に使用される。(参考)
- Azure CLI: Azure CLI (az コマンド) のクレデンシャルを使用する方式。ローカル環境で MCP サーバーを試す場合に使用される。(参考)
- Azure PowerShell: Azure PowerShell のクレデンシャルを使用する方式。ローカル環境で MCP サーバーを試す場合に使用される。(参考)
詳細に関しては、下記を参照してください。
セットアップ方法
2026 年 6 月現在、Azure MCP Server は stdio トランスポートと SSE をサポートしています。ただし、SSE は非推奨の状態 なので、stdio を採用するのが良いでしょう。
主なセットアップ方法は、次の 2 種類あります。
-
Node.js:
npx
やnpm
を使用して Azure MCP Server を起動する方法。Node.js のランタイム環境が必要です。 - コンテナ: コンテナとして Azure MCP Server を起動する方法。Docker や containerd など、コンテナ ランタイムがインストールされている必要があります。
たとえば、VS Code (GitHub Copilot) で Azure MCP Server を Node.js で実行する場合、次のように設定します。
settings.json
{
"mcp": {
"servers": {
"azure-mcp-server": {
"command": "npx",
"args": [
"-y",
"@azure/mcp@latest",
"server",
"start"
]
}
}
}
}
--service
オプションは、MCP Server の起動時に特定のサービスを指定するためのものですが、通常は省略しても問題ありません。azcmp-log-query
ツールだけが必要な場合は、--service monitor
を指定してツールを限定できます。
Docker コンテナで Azure MCP Server を実行する場合は、次のように設定します。.env
ファイルを指定している理由は、環境変数による認証方式を利用しているためです。詳しくは 公式ドキュメントのセットアップガイド を参照してください。
settings.json
{
"mcp": {
"servers": {
"azure-mcp-server": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--env-file",
"/full/path/to/.env",
"azure/azuremcp"
]
}
}
}
}
自動インシデント対応の流れ
この記事では、次のような Azure MCP Server を使ったインシデント対応を提案します。
このフローにおいて、インシデント対応者が実施しなければならないことは 2 つです。
- トラブルシューティング ガイドを記述する: エージェントがどのような手順でログ調査を行うべきかを自然言語で記述します。たとえば、発行すべき KQL クエリの雛形、ログの解釈の方法などを整理して記述します。実行時のプロンプトが短くなるので、静的な情報 (例: 参照先の Log Analytics ワークスペース) を記述するのもオススメです。なお、エージェントが正しく解釈できない可能性があるので、出来るだけ簡潔に必要十分な情報だけを記述することが重要です。
- トラブルシューティングの実行を依頼する: LLM アプリケーション (例: Claude Desktop、VS Code / GitHub Copilot) に、トラブルシューティングの実行を依頼します。たとえば、「YYYY-MM-DD mm:ss 頃に発生した障害の原因を調査してください」といった具合です。この際、アプリケーションがトラブルシューティング ガイドを参照する必要があります。外部リンクや外部コンテンツをコンテキストとして付与するか、プロンプトにトラブルシューティング ガイドを丸ごと含めます。
ステップ 2 を実行すると、多くの場合、アプリケーションは実行に必要な情報を確認した上で、Azure MCP Server のログ検索ツールを実行しようとするはずです。情報が足りていなければ、「~の ID は何ですか?」のように確認を促してくれるでしょう (動作はモデルやエージェントの実装依存)。必要な情報が揃っていれば、トラブルシューティング ガイドに従ってログを取得し、結果を分析してくれます。
トラブルシューティングガイドの記述方法
先述の通り、トラブルシューティング ガイドは、エージェントがインシデント対応を行うための手順を記述したドキュメントです。具体的には、次のような内容を記述します:
トラブルシューティングガイドの例
tsg-s2s-vpn.md
# TSG: S2S VPN 接続が切れた
これは、S2S VPN 接続が切れた場合の診断と原因分析を記述したトラブルシューティングガイドです。
## 環境情報
### VPN Gateway
- ResourceId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-azure-mcp/providers/Microsoft.Network/virtualNetworkGateways/vpngw-azure
### 接続先
1. conn-to-onprem
- Remote IP: x.x.x.x
- IP Addresses: 192.168.0.0/16
### Log Analytics ワークスペース
- SubscriptionId: 00000000-0000-0000-0000-000000000000
- ResourceGroupName: defaultresourcegroup-sea
- WorkspaceName: DefaultWorkspace-00000000-0000-0000-0000-000000000000-SEA
- TableType: Microsoft
## 注意事項
- Azure MCP Server の `monitor-log-query` ツールを使用して、Log Analytics ワークスペースからログをクエリします。ただし、hours パラメータには 24 や 48 など、ログを含むのに十分大きなウィンドウを指定します。より詳細な時間の絞りこみは、`TimeGenerate` に対する where 句で指定します。
- クエリを実行する際は、`{VpnGatewayResourceId}` などのテンプレート変数を適切な値に置き換えてください。
## トラブルシューティング手順
### 1. トンネルの状態確認
VPN トンネル状態を確認し、接続が正常に確立されているかを確認します。下記のクエリを実行し、最終的なトンネルの状態を確認します。
```kql
AzureDiagnostics
| where TimeGenerate between (datetime({StartTime}) .. datetime({EndTime}))
| where Category == "TunnelDiagnosticLog"
| where ResourceId =~ "{VpnGatewayResourceId}"
| where remoteIP_s == "{RemoteIP}"
| project TimeGenerated, OperationName, status_s, stateChangeReason_s, instance_s
```
最後の状態が "Connected" であれば正常に接続されていることを意味します。
### 2. IKE ログの確認
下記のクエリを実行し、最期のセッションでの IKE デバッグログを確認します。
```kql
AzureDiagnostics
| where TimeGenerate between (datetime({StartTime}) .. datetime({EndTime}))
| where Category == "IKEDiagnosticLog"
| where ResourceId =~ "{VpnGatewayResourceId}"
| where Message has "{RemoteIP}"
| project TimeGenerated, Message
| sort by TimeGenerated asc
```
IKE ログは、VPN ゲートウェイと対向デバイス双方の IKE メッセージのやり取りを記述しています。下記は、正常な IKE セッションのシーケンス例 (Sender の場合) です。
```plaintext
[SEND][SA_INIT] Sending IKE SA_INIT packet with tunnelId 0x1, iCookie 0xA9261CDE9DABECD and rCookie 0x0
[RECEIVED]Received Ike payload: Policy1:Cipher=AES-CBC-256 Integrity=SHA1 DhGroup=DhGroup2 Policy2:Cipher=AES-CBC-256 Integrity=SHA256 DhGroup=DhGroup2 Policy3:Cipher=AES-CBC-128 Integrity=SHA1 DhGroup=DhGroup2 Policy4:Cipher=AES-CBC-128 Integrity=SHA256 DhGroup=DhGroup2 Policy5:Cipher=3DES Integrity=SHA1 DhGroup=DhGroup2 Policy6:Cipher=3DES Integrity=SHA256 DhGroup=DhGroup2
[RECEIVED] Receiving MM Packet for tunnel Id 0x0 iCookie 0x3E90974C33F7F48B and rCookie 0xAFADDC42504E1BD: Receiving MM Nonce
[SEND][SA_INIT] Sending IKE SA_INIT response packet with tunnelId 0x0, iCookie 0x3E90974C33F7F48B and rCookie 0xAFADDC42504E1BD
[SEND]Sending Ike payload for tunnel Id 0x0: Auth:PreShared Key- Responder Policy:Cipher=AES-CBC-256 Integrity=SHA1 DhGroup=DhGroup2
[RECEIVED][SA_AUTH] Received IKE AUTH message
[RECEIVED]Received Traffic Selector payload request- [Tsid 0x1 ]Number of TSIs 1: StartAddress 0.0.0.0 EndAddress 255.255.255.255 PortStart 0 PortEnd 65535 Protocol 0 Number of TSRs 1:StartAddress 0.0.0.0 EndAddress 255.255.255.255 PortStart 0 PortEnd 65535 Protocol 0
[SEND] Proposed Traffic Selector payload will be (Final Negotiated) - [Tsid 0x1 ]Number of TSIs 1: StartAddress 0.0.0.0 EndAddress 255.255.255.255 PortStart 0 PortEnd 65535 Protocol 0 Number of TSRs 1:StartAddress 0.0.0.0 EndAddress 255.255.255.255 PortStart 0 PortEnd 65535 Protocol 0
[RECEIVED]Received IPSec payload: Policy1:Cipher=AES-GCM-256 Integrity=AES-GCM-256 Policy2:Cipher=AES-CBC-256 Integrity=SHA1 Policy3:Cipher=3DES Integrity=SHA1 Policy4:Cipher=AES-CBC-256 Integrity=SHA256 Policy5:Cipher=AES-CBC-128 Integrity=SHA1 Policy6:Cipher=3DES Integrity=SHA256
[SEND][SA_AUTH] Sending SA AUTH response message for tunnelId 0x2 and tsId 0x1
[SEND]Sending IPSec policy Payload for tunnel Id 0x2, tsId 0x1: Policy1:Integrity=AES-GCM-256 Cipher=AES-GCM-256
[LOCAL_MSG] IKE Tunnel created for tunnelId 0x2
```
```
当然、ガイドに何を含めるかはシナリオ依存になりますが、おおよそ以下のような内容を含めると良いでしょう。
- トラブルシューティングガイドの概要: どのような場合をスコープしたガイドなのか、どのような目的で使用するのかを簡潔に記述します。
- 環境情報: トラブルシューティングを行うために必要な情報を明記します。たとえば、対象リソースのリソース ID、接続先の IP アドレス、Log Analytics ワークスペースの情報などを記述します。これらの情報は、エージェントが実行する操作に必要な情報となります。
- 診断の手順: どのような操作を実行するのかを具体的に記述します。たとえば、Log Analytics ワークスペースで発行するクエリのひな形や、Azure CLI コマンドの例などを記述します。
- 結果の解釈方法: 取得した情報をどのように解釈するのか、どのような結果が期待されるのかを記述します。たとえば、特定のエラーコードが返された場合の対処方法や、ログのパターンをどのように分析するかなどを記述します。正常・異常時のログパターン サンプルなどを記載するのも良いでしょう。
- 参考情報: 追加の参考情報やドキュメントへのリンクを記述します。たとえば、Azure の公式ドキュメントや、過去の類似インシデントへのリンクなどを記述します。
- 注意事項: トラブルシューティングを行う際の注意点を記述します。たとえば、ログ検索時の時間範囲の指定方法や、Azure MCP Server ツールの使い方を記述します。
記述は Markdown などの構造的なフォーマットで行うと、エージェントが内容を理解しやすくなります (例: クエリと通常の文の違いが明確になる)。人間が見たときにもわかりやすく、エージェントが実行する際にも適切に解釈されるでしょう。
また、実際の運用の現場では、このようなトラブルシューティングガイドを準備することが大きな課題になると予想されます。経験値の高いエンジニアを中心に、過去の対応ログを見ながら手順を整理していくことが重要です。
動作デモ
例示した S2S VPN のトラブルシューティング ガイドを実際に使用して、どのような動作をするのかをデモ動画で紹介します。
この動画で想定するシナリオは、オンプレミス拠点の VPN デバイスと VPN Gateway 間のトンネル切断事象です。オンプレミス拠点のデバイス上でリセットを実施し、意図的に切断を発生させた後、その時刻の調査を GitHub Copilot に依頼しています。
以下が最終的な Copilot の回答です。回答の生成に要した時間は、30 秒程度でした。
VPN 切断事象の調査報告(2025/6/18 7:20ごろ)
1. トンネル状態ログの概要
- 7:23:02 トンネル接続(Connected)
- 7:50:57 トンネル切断(Disconnected, Remotely triggered)
- 7:50:58 トンネル再接続(Connected)
2. IKE ログの抜粋
- 7:22:14 「Negotiation timed out」により一度トンネルが閉じられたが、その後正常に再接続。
- 7:50:57 「Received IPSec SA delete」「Main mode SA lifetime expired or peer sent a main mode delete」によりトンネル切断。
- 7:50:58 直後に再接続処理が行われ、IKE/SA/Traffic Selector/IPSec 交渉も正常に完了。
3. まとめ
- 7:50:57(UTC)にVPNトンネルが「Remotely triggered」により切断されました。
- ログ上は、対向機器からのSA削除やSAライフタイム満了が原因で切断されたことが示唆されます。
- 切断直後に自動的に再接続が行われ、IKE/IPSecネゴシエーションも正常に完了しています。
- 一時的な切断であり、継続的な障害は発生していません。
参考ログ(抜粋)
2025/06/18 7:50:57 [TunnelDisconnected] Disconnected (Remotely triggered) 2025/06/18 7:50:57 [RECEIVED][SA_DELETE] Received IPSec SA delete message for tunnelid 0x2 and tsid 0x1 2025/06/18 7:50:57 [LOCAL_MSG] IKE Tunnel closed for tunnelId 0x2 with status Main mode SA lifetime expired or peer sent a main mode delete. 2025/06/18 7:50:58 [TunnelConnected] Connected (RemotelyTriggered)
対応
- 今回の切断は対向機器側の操作またはSAライフタイム満了によるもので、Azure側の異常は見られません。
- 継続監視を推奨しますが、現時点で追加対応は不要です。
回答内容は正確です。最初、ユーザーは「UTC 7:20 ごろ」と時間を指定していますが、これは実は誤った時間で、本当は 7:50 頃に対向ルーターでトンネルのリセット操作をしていました。トラブル対応をしていると、ユーザー報告時間が間違っていることが多々あるので敢えてこのような実験をしてみましたが、今回はうまくいきました。
また、この回答を生成するにあたり、GitHub Copilot は次のような手順を実行しています。
-
トンネル状態ログの取得:
AzureDiagnostics
テーブルから、事象発生時刻のトンネル状態ログを取得し、最終的なトンネルの状態を確認する。 -
IKE ログの取得:
AzureDiagnostics
テーブルから、事象発生時刻付近の IKE デバッグログを取得し、トンネル切断の原因となった IKE メッセージのやり取りを確認する。 - 結果の分析: 取得したログを分析し、トンネル切断の原因や再接続の状況をまとめる。
ほとんどトラブルシューティングガイドの通りに実行してくれていますが、コンテキストに合わせた微調整も行ってくれています。たとえば、次のような細かい修正などが行われていました:
-
TimeGenerate
の時間範囲の指定をbetween (datetime(2025-06-18T07:00:00Z) .. datetime(2025-06-18T08:00:00Z))
に指定。スニペットでは{StartTime}
と{EndTime}
のテンプレート変数を使用していましたが、実際の時間に置き換えてくれています。 - ログ取得時の最大数を 100 件に指定。あまり膨大なログを取得しないように、適切な件数に制限してくれています。
-
sort by TimeGenerated asc
の追加。Tunnel 状態ログを取得するテンプレート クエリに、時間順ソートの処理がなかった点を補完してくれています。
このような補完能力は、主に使用される言語モデルの能力に依存するものです。もし強力なモデルが使えない場合や、期待したような動作にならない場合は、プロンプトの指定やトラブルシューティングガイドの記述を見直す必要があります。
応用の可能性
今回紹介した活用方法は、あくまで一例です。Azure MCP Server を活用することで、様々なインシデント対応の自動化が可能になります。たとえば、次のような応用が考えられます。
- 定期的な監視とアラート: 定期的にログ調査の指示を出しておけば、異常を検知し、アラートを発行する仕組みを構築できます。これにより、メトリックやログのクエリだけでは判断できない、ニュアンスを含んだ問題 (例: Gray Failure) の特定につながり、予防的な対応がより容易になります。
- ヒーリングの提案と自動化: 診断後のアクションも併せて提案することも出来ます。たとえば、VPN 接続の状態が異常であることがわかった場合に、自動的に LLM が VPN Gateway のリセットを促すような仕組みです。また、Azure MCP Server では Azure CLI コマンドを実行できるため、ユーザーの許可を得て自動的にリセットを実行することも可能です。これにより、問題の解決までの時間を大幅に短縮できます。
- 複数のログの連携: 複数の Azure リソースを連携させて、より複雑なトラブルシューティングを自動化することができます。たとえば、ネットワークの問題が発生した場合に、関連する仮想マシンやストレージアカウントの状態を横断的に確認し、総合的に判断して問題の原因を特定することができます。
- ユーザー インターフェースの改良: 今回の機能をボット化すれば、Teams や Slack などのチャットアプリケーションからも簡単に操作できるようになります。また、トラブルシューティング ガイドのピックアップもあわせてやってもらえるように、多機能化/マルチエージェント化するという改良も考えられます。
- トラブルシューティング ガイドの自動生成: トラブルシューティングガイドは人間の対応履歴を基に作成できます。過去の対応履歴がコミュニケーションツールやチケット管理システム上で保管されている場合、AI を活用して自動的にトラブルシューティングガイドを生成することも可能です。これにより、ガイドの作成負荷を軽減し、迅速な対応が可能になります。
まとめ
Azure MCP Server を活用することで、Azure 上のインシデント対応を効率化することができます。特に、トラブルシューティング ガイドを記述し、エージェントに実行させるフローが Azure MCP Server で容易に実現できます。
本記事では、サンプルとして S2S VPN 接続のトラブルシューティングをメインに、トラブルシューティングガイドの記述方法や実際の動作を紹介しました。デモ動画では、おおよそ 30 秒程度 で事象の診断が完了できましたが、これを人間が手動で行う場合、慣れているエンジニアでも数分から十数分はかかりますし、レポートの生成も含めると 30 分程度の時間がかかってもおかしくありません。一度仕組みを整えれば、エージェントが数十倍の速さで問題を解決してくれることになります。
このような自動化の取り組みは、インシデント対応の負荷を軽減し、より迅速な問題解決を実現するために非常に有効です。今後も、AI や MCP の活用が進むことで、インシデント対応の効率化がさらに進むことが期待されます。
Views: 0