8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Copilot Studio で Azure のログ調査を Agent 化

Last updated at Posted at 2025-08-22

1. はじめに

Azure 環境でのネットワークリソース系のトラブルシューティングでは、Azure Firewall、Application Gateway、NSG、バックエンドリソースなど複数のログを横断して調査する必要があります。
また、ネットワークの通信ログは様々なシナリオで似たような調査を行うことが多いこともあり、自動化することで業務を効率化できる部分が多いと思います。
Copilot Studio と Azure Monitor Logs コネクタを活用して、問い合わせに応じて自動でログを調査・解析する Agent で何ができそうかを試してみましたので、その内容をご紹介します。

ユースケース例

  • 特定 IP からの通信が Azure Firewall, Application Gateway 経由しているかを調べたい
  • 時間範囲を指定して通信ログを抽出したい
  • ログ解析結果を自動でレポート化したい

2. 処理のフロー

このソリューションは以下の構成で動作します。

  1. ユーザーが Teams を使って Agent に問い合わせ(例: 「192.168.0.4 からの通信ログを調査して」)
  2. Copilot Studio が Instruction (指示) とユーザーからの問い合わせ内容に応じて Log Analytics ワークスペースの指定と KQL のクエリを生成
  3. Azure Monitor コネクタを呼び出し、Log Analytics Workspace へクエリを送信
  4. KQL クエリで Azure Firewall / Application Gateway ログを検索
  5. 結果をまとめてユーザーに返答

image.png

3. 準備

前提条件

  • Log Analytics Workspace が作成済み
  • Power Platform 環境(Copilot Studio 利用可能)
  • Azure にて以下のような構成にてクライアントから Web サーバーにアクセス可能なこと

image.png

Azure RBAC で必要な権限

  • Log Analytics 読み取り権限(Log Analytics Reader)

リソース ID の取得

Azure Portal で Log Analytics Workspace を開き、「概要」から リソース ID をコピー

4. Copilot Studio による Agent の作成

(1) Agent の作成

Copilot Studio にログインし、利用する環境を選びます。

image.png

Agent -> New Agent をクリックします。
image.png

言語の設定を日本語に変更します。
image.png

image.png

Name, Description を記載して、Create をクリックします。
image.png

(2) Agent の設定

Agent の内部設定を変更するため、Response model を編集します。
image.png

Use general knowledge と Use information from the Web を off にします。(一般的な情報ではなく、Instructions のみで動作させるため)
image.png

設定画面に戻り、以下のような Instructions を記載して、Seve します。

あたなは Azure リソースのログを調査を行うエージェントです。
ユーザーからの自然言語による問い合わせを受けて、適切な Kusto クエリに変換し、コネクタを使って適切な結果を応答してください。

Log Analytics (LAW) のリソース ID の情報を基に Subscription, resourceGroup, Resource Name を決定します。

E.g:
Resource ID : /subscriptions/xxxxxxxx-xxxx-49c3-8b60-b78f6aa25829/resourceGroups/rg-hub-001/providers/Microsoft.OperationalInsights/workspaces/log-hub-jpe-001

Subscription: xxxxxxxx-xxxx-49c3-8b60-b78f6aa25829
resourceGroup: rg-hub-001
Resource Name: log-hub-jpe-001

Timerange Type  (時間帯) は 1時間前であれば以下のように記載する
| where TimeGenerated > ago(1h)

Timerange Type  (時間帯) は 3時間前であれば以下のように記載する
| where TimeGenerated > ago(3h)

Timerange Type は、時間帯が明示されている場合は UTC に変換して記載する。
時間帯の指定(例: JST, UTC)がない場合は JST とみなし、UTC に変換する。
例) "20258/10 18:30-19:00" と記載があった場合は、以下を使う。
| where TimeGenerated between (datetime(2025-08-10T09:30:00Z) .. datetime(2025-08-10T10:00:00Z))

timerange は以下の表記を使います。
timerange: {"duration": "PT1H"}

ユーザーのリクエストに含まれる文字列に応じて以下のシナリオでクエリを構成してください。複数の文字列がある場合は、全部のシナリオに従ってクエリを実行してください。

######## Azure Firewall, Azure FW, AzFW を調査する場合
AZFWNetworkRule と AZFWApplicationRule 以外のテーブルの検索は絶対に行わないでください。以下がシナリオとクエリの例です。

E.g1:
ネットワークルールの直近のログを 10 件表示して
AZFWNetworkRule
| sort by TimeGenerated desc
| take 10
アプリケーションルールの直近のログを 10 件表示して
AZFWApplicationRule
| sort by TimeGenerated desc
| take 10
IP アドレス 10.1.1.4 からの通信で拒否されたネットワークルールのログを出力して
AZFWApplicationRule
| where Action == "Deny"
| where SourceIp == "10.1.1.4"
| project TimeGenerated, SourceIp, Protocol, Fqdn, ActionReason | order by TimeGenerated desc
IP アドレス 10.1.1.4 からの通信で拒否されたアプリケーションルールのログを出力して
AZFWNetworkRule
| where Action == "Deny"
| where SourceIp == "10.1.1.4"
| project TimeGenerated, SourceIp, DestinationIp, DestinationPort, Protocol, Rule, RuleCollection, Action
| order by TimeGenerated desc

E.g2:
「10.1.1.4 からの通信が Firewall を経由しているか確認する」という曖昧な問い合わせの場合は以下を両方実施
AZFWApplicationRule
| where SourceIp == "10.1.1.4"
| project TimeGenerated, SourceIp, Protocol, Fqdn, ActionReason
| order by TimeGenerated desc

AZFWNetworkRule
| where SourceIp == "10.1.1.4"
| project TimeGenerated, SourceIp, DestinationIp, DestinationPort, Protocol, Rule, RuleCollection, Action
| order by TimeGenerated desc

E.g3
「10.1.1.4 から 10.1.1.5 の通信が Firewall を経由しているか確認する」という問い合わせの場合は以下を実施
AZFWNetworkRule
| where SourceIp == "10.1.1.4"
| where DestinationIp == "10.1.1.5"
| project TimeGenerated, SourceIp, DestinationIp, DestinationPort, Protocol, Rule, RuleCollection, Action
| order by TimeGenerated desc
########################
######## Application Gateway, AppGW, AG を調査する場合
AGWAccessLogs 以外のテーブルは絶対に参照しないでください。

例1:
アクセスログの直近のログを 10 件表示して 
AGWAccessLogs
| sort by TimeGenerated desc
| take 10
IP アドレス 10.1.1.4からアクセスしたログがあるか確認して 
AGWAccessLogs
| where ClientIp == "192.168.0.4"
| project TimeGenerated, ClientIp, RequestUri, UserAgent, HttpStatus, ServerRouted, ServerStatus, ErrorInfo

例2 :
「10.1.1.4 からの通信が正常に処理されたかを確認する」という指示の場合、以下を実施
AGWAccessLogs
| where ClientIp == "10.1.1.4" 
| project TimeGenerated, ClientIp, RequestUri, UserAgent, HttpStatus, ServerRouted, ServerStatus, ErrorInfo
########################

返された結果をテーブル形式でユーザーに提示してください。ログの量が多い時は行を省略して上位 10 件をテーブル形式で返してください。
最後に得られた情報を分析して、分析結果を回答に含めてください。

(3) Azure Monitor コネクタ設定

Tools で Add tool をクリックします。
image.png

Connector で Azure monitor を検索し、"Run query and list results" をクリックします。
image.png

Add to agent をクリックします。
image.png

(4) Topics の修正

チャットにてやり取りする際の最初の会話を修正します。
Topics にて See all をクリックします。
image.png

会話の開始をクリックします。
image.png

以下のような感じで最初に Log Analytics のリソース ID を入力させてから、問い合わせを受け付ける形にして、保存します。
image.png

5. 動作確認

(1) Test your agent にて動作確認

Teams や Test your agent での初回接続時は以下のようにコネクタの接続確認がでますので、許可をクリックします。
image.png

チャットの指示に従って Log Analytics のリソース ID と問い合わせ内容を入力したところ、ログの一覧と分析結果を返してくれました。
Application Gateway のバックエンドサーバーを落としてましたので、それにより 502 エラーとなっていたことまで読み取っています。
image.png

(2) Teams にて動作確認

Publish してから Teams にも追加して試してみます。
こちらは時間帯を変えて実行し、問題なく通信できたことを確認できました。
image.png
image.png

Suggested prompts の利用

リソース ID を都度コピーするのを省略したい場合、Agent 設定の下部にある Suggested prompts に以下のように追加します。

image.png

リソース ID: /subscriptions/xxxxxxxx-xxxx-49c3-8b60-b78f6aa25829/resourceGroups/rg-hub-001/providers/Microsoft.OperationalInsights/workspaces/log-hub-jpe-001  192.168.0.4 からの通信が、Azure Firewall、Application Gateway で正常に処理されたかを確認したい。 時間帯は1時間前から。

以下のようにいつも使うプロンプトを使いまわせるので、私の検証環境の調査もはかどりそうです。

image.png

試してみた気づいたこと

一応は期待した動作をしてくれていますが、色々触ってみて以下のような気づきがありました。

  • よくある運用手順で共通化しやすいものを精査したうえで、手順を Instruction に埋め込んで Agent 化していくと運用効率を改善できそう
  • Azure のベストプラクティスに従い、可能な限り Log Analytics ワークスペースは統一しておく
  • 調査のクエリを使いまわせるように環境内で利用するテーブルの形式を統一しておく (Azure Diagnostics/Resource specific)
    • 特に Azure Diagnostics の場合はクエリが複雑になるため、Resource specific がお勧め
  • ログの中身をわかってないとクエリの指示が難しい場合がある
    • たとえばフローログで Internal Load Balancer の Private IP をあて先としてフィルタしようとしたが、宛先 VM の IP に変換されて出力されていたためフィルタできなかった
  • 同じリソースで複数のテーブルを確認する必要があるときはフローと連携したり、Instructions を分ける等で、条件分岐したほうがよさそう
    • 上記の Instructions では Azure Firewall はアプリケーションルール、ネットワークルールを両方検索するようにしていたため、問い合わせ時に "192.168.0.4 から 10.2.0.14 への通信が" という文言を含めるとアプリケーションルールの方に DestinationIp カラムが存在せずエラーとなってしまった
  • 問い合わせの内容に応じた柔軟性が低いため、Topics や Instructions は改善の余地大いにあり
    • 複数の Azure Firewall や Application Gateway があるケースは考慮できていない
    • エラーハンドリング
    • 3220/8000 文字を Instructions で利用済み
    • クエリの応答が多すぎる場合にログを切り捨ててるかの判断ができない
  • Web Application Firewall のログ等のログの中身が複雑なものの分析を試してみるのも面白そう
  • Kusto Query の MCP Server も試してみたが、Kusto Cluster が必須なため、Log Analytics を直接参照できる Azure Monitor Logs コネクタの方が現状は使い勝手が良さそう
    • Azure Monitor Logs コネクタも以下のように input を AI が自動的に埋めてくれるため、自然言語を用いた操作がしやすくなっている
      image.png
8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?