はじめに
Application Insights や Log Analytics Workspace を「閉域化したい」となったとき、必ず登場するのが Azure Monitor Private Link Scope (AMPLS) です。最初は「なぜ Workspace 単独で Private Endpoint を生やせないのか」「scope って何を束ねているのか」が分かりにくく、ハマりがちです。
この記事では、別検証で実際に AMPLS を PrivateOnly モードで構築し、テレメトリ送信と公開拒否を実証した経験を踏まえて、AMPLS の役割を 4 点に整理 します。
本記事記述および実装内容は、多くの部分をAIで処理しており、人間チェックは甘いです
TL;DR
- AMPLS は Application Insights / Log Analytics / Data Collection Endpoint を Private Link 経由でアクセスさせるための「束ね役 (scope)」リソース
- Workspace や Component に 直接 Private Endpoint は張れない。AMPLS にだけ張れる
-
accessModeSettingsをPrivateOnlyにすると、AMPLS にリンクされた Workspace / Component への public IP アクセスを Workspace 自身の設定とは無関係に拒否 できる("weakest link" 性質) - AMPLS 自体のアクセスログは取れない(Diagnostic Settings 非対応)
-
az monitor private-link-scope showにはaccessModeSettingsを返さないバグがあるので REST API 直叩きが必要
なぜ "scope" という概念が必要なのか
Application Insights / Log Analytics Workspace は 共有エンドポイント にテレメトリを流す集約サービスです。
| エンドポイント | 用途 |
|---|---|
dc.applicationinsights.azure.com |
Application Insights ingestion (古い classic 経路) |
*.in.applicationinsights.azure.com |
Application Insights ingestion (region 別) |
*.ods.opinsights.azure.com |
Log Analytics ingestion |
*.oms.opinsights.azure.com |
Log Analytics agent / API |
*.agentsvc.azure-automation.net |
LAW agent service config |
これらはすべて Microsoft 側が管理する共有 FQDN で、Workspace ごとにエンドポイントを切り出していません。そのため Workspace に直接 Private Endpoint を生やすことはできず、「どの Workspace と Component を Private Link 経由でアクセスさせるか」を一括宣言する scope オブジェクトが必要 になります。それが AMPLS です。
AMPLS の 4 つの役割
役割 1: Private Link 経由のアクセス経路提供
VNet 内クライアントからのテレメトリ ingestion / log query を Private IP 経由 にする。Private Endpoint を AMPLS に対して 1 本張れば、AMPLS にリンクされた すべての Workspace / Component / DCE にその経路が適用されます。
PE の groupId は azuremonitor 一択です。
役割 2: 閉域モードの強制 (accessModeSettings)
AMPLS には 2 つのアクセスモード設定があります。
| 設定 | 値 | 効果 |
|---|---|---|
ingestionAccessMode |
Open / PrivateOnly
|
AMPLS にリンクされた Workspace / Component への ingestion の振る舞い |
queryAccessMode |
Open / PrivateOnly
|
同 query の振る舞い |
PrivateOnly にすると、AMPLS にリンクされた Workspace / Component への public IP からの ingestion / query を、Workspace 自身の publicNetworkAccess 設定が Enabled であっても拒否 します。
これが "weakest link" (最弱リンク) 性質 と呼ばれるもので、1 つでも PrivateOnly な AMPLS にリンクされていれば、その Workspace / Component は閉域になります。
逆に言うと、PrivateOnly にした AMPLS と Workspace を紐付けたら、VNet 内に PE を張る前にアクセスが切断されます。先に PE を張ってから紐付ける か、構築時は一時的に Open にしておく運用が安全です。
Bicep で書くとこんな感じです。
resource ampls 'Microsoft.Insights/privateLinkScopes@2021-07-01-preview' = {
name: amplsName
location: 'global'
properties: {
accessModeSettings: {
ingestionAccessMode: 'PrivateOnly'
queryAccessMode: 'PrivateOnly'
}
}
tags: tags
}
resource scopeAppI 'Microsoft.Insights/privateLinkScopes/scopedResources@2021-07-01-preview' = {
parent: ampls
name: 'scope-appi'
properties: {
linkedResourceId: appInsightsId
}
}
resource scopeLAW 'Microsoft.Insights/privateLinkScopes/scopedResources@2021-07-01-preview' = {
parent: ampls
name: 'scope-law'
properties: {
linkedResourceId: logAnalyticsWorkspaceId
}
}
API version は 2021-07-01-preview 以降が必須です。古い 2019-10-17-preview は accessModeSettings を受け付けません。
役割 3: 紐付くリソースの宣言 (scopedResources)
どの Workspace / Component / DCE がこの scope に属するかを scopedResources 子リソースで明示します。
| linkedResourceId に指定可能 | 例 |
|---|---|
| Application Insights | Microsoft.Insights/components |
| Log Analytics Workspace | Microsoft.OperationalInsights/workspaces |
| Data Collection Endpoint | Microsoft.Insights/dataCollectionEndpoints |
複数の AMPLS にリンクすることも可能ですが、weakest-link 性質と相まって挙動が予測しにくくなるため非推奨です。
役割 4: Private DNS の振り分け基盤
AMPLS の Private Endpoint は 共有エンドポイントの FQDN を private IP に解決させる ために、複数の Private DNS Zone を必要とします。
| Private DNS Zone | 解決対象 | 用途 |
|---|---|---|
privatelink.monitor.azure.com |
AMPLS グローバルエンドポイント | scope 制御 |
privatelink.oms.opinsights.azure.com |
LAW agent / OMS endpoint | 設定 / heartbeat |
privatelink.ods.opinsights.azure.com |
LAW data ingestion | ログ送信本体 |
privatelink.agentsvc.azure-automation.net |
LAW agent service config | エージェント設定 |
さらに Application Insights の Profiler / Snapshot Debugger を使う場合は privatelink.blob.core.windows.net も追加が必要です。
DNS Zone は VNet にリンク (virtualNetworkLinks) しないと名前解決されません。Bicep で 4 ゾーン分まとめると以下のようになります。
var amplsZones = [
'privatelink.monitor.azure.com'
'privatelink.oms.opinsights.azure.com'
'privatelink.ods.opinsights.azure.com'
'privatelink.agentsvc.azure-automation.net'
]
resource zones 'Microsoft.Network/privateDnsZones@2024-06-01' = [for z in amplsZones: {
name: z
location: 'global'
tags: tags
}]
resource links 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2024-06-01' = [for (z, i) in amplsZones: {
parent: zones[i]
name: 'link-${vnetName}'
location: 'global'
properties: {
registrationEnabled: false
virtualNetwork: { id: vnetId }
}
}]
AMPLS なしだと何が起きるか
Workspace / Component の publicNetworkAccessForIngestion を Disabled にしただけでは、VNet からのアクセス経路が用意されない ので、結果として「ingestion 完全停止」になります。
つまり以下のような状態は閉域化ではなく機能停止です。
- Workspace の
publicNetworkAccessForIngestion = Disabled - Workspace の
publicNetworkAccessForQuery = Disabled - AMPLS 未作成 / Private Endpoint 未作成
AMPLS は 「閉域にしつつテレメトリは流す」 ための唯一の手段です。Workspace / Component 単独の Private Endpoint は存在しません。
実検証で確認した動作(参考)
別検証で Functions (Python EP1) + AMPLS PrivateOnly + AppI / LAW 構成を組み、以下を実証しました。
| 観点 | 観測結果 |
|---|---|
| VNet 内 (Jumpbox) からのテレメトリ送信 | AppI requests テーブル / LAW AppRequests テーブルに 8 件完全到達 (ロス 0) |
| public IP からの AppI ingestion POST | HTTP 403 Component has publicNetworkAccessForIngestion=Disabled
|
| public IP からの LAW query REST | HTTP 403 Access from <ip> is denied
|
Function App inbound (*.azurewebsites.net) public アクセス |
HTTP 403 (PE inbound 構成のため別の話だが完全閉域化を確認) |
| AMPLS 自体のアクセスログ | 取得不可 (Diagnostic Settings 非対応) |
Public IP からの AppI ingestion 拒否の様子(実例)
実コマンドと実レスポンスです。
# 自宅 (public IP) から AppI の ingestion endpoint に直接 POST
$ curl -i -X POST "https://dc.applicationinsights.azure.com/v2/track" \
-H "Content-Type: application/json" \
-d '{ "iKey": "<INSTRUMENTATION_KEY>", ... }'
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"itemsReceived": 1,
"itemsAccepted": 0,
"errors": [{
"index": 0,
"statusCode": 403,
"message": "Component has publicNetworkAccessForIngestion=Disabled, ingestion is not allowed."
}]
}
403 と一緒に明示的なエラーメッセージが返ってくるので、デバッグが楽でした。
注意点(実装で踏みやすい罠)
罠 1: AMPLS 自体のアクセスログは取れない
Microsoft.Insights/privatelinkscopes は Diagnostic Settings 非対応 (ResourceTypeNotSupported) です。「誰が PE 経由で AMPLS を使ったか」を直接ログに残すことはできません。観測したい場合は Activity Log や NSG flow logs に依存することになります。
罠 2: Azure Portal の Logs 画面は PrivateOnly でも見える
Portal は Microsoft バックボーン経由 でアクセスするため、PrivateOnly 設定下でも Portal の Logs / Application Map は普通に見えます。これは仕様であって設計通りです。
「閉域化したのに Portal で見えるのは穴では?」と心配しがちですが、Portal アクセスは AAD 認証 + ロール (Log Analytics Reader 等) で守られている前提です。完全に Portal も塞ぎたい場合は AAD 条件付きアクセスや IP 制限で別途対応してください。
罠 3: az monitor private-link-scope show のバグ
Azure CLI の az monitor private-link-scope show コマンドは、レスポンスに accessModeSettings を含めません。PrivateOnly 設定の確認には REST API を直叩きする必要があります。
SUB="<SUBSCRIPTION_ID>"
RG="rg-private-app-insights-dev"
NAME="ampls-pappi-dev-jpe"
az rest --method GET \
--uri "https://management.azure.com/subscriptions/$SUB/resourceGroups/$RG/providers/microsoft.insights/privateLinkScopes/$NAME?api-version=2021-07-01-preview" \
--query "properties.accessModeSettings"
返り値:
{
"exclusions": [],
"ingestionAccessMode": "PrivateOnly",
"queryAccessMode": "PrivateOnly"
}
罠 4: 構築順序を間違えるとアクセス断
前述の通り、PrivateOnly AMPLS と Workspace を紐付けると、PE 経由以外のアクセスが切断されます。
推奨順序:
- AMPLS を
accessMode = Openで作成 - Private Endpoint を AMPLS に張る(VNet 内に Private IP 確保)
- Private DNS Zone 4 つ + VNet link を作成
- Workspace / Component を AMPLS に scopedResource として追加
- Workspace / Component の
publicNetworkAccessをDisabledに変更 -
最後に AMPLS の accessMode を
PrivateOnlyに切り替え
Bicep で dependsOn を効かせて 1 回のデプロイでこの順序を担保するのが理想ですが、初回構築時は段階的にやるのが安全です。
罠 5: Profiler / Snapshot Debugger 用の追加 DNS Zone
AppI の Profiler / Snapshot Debugger は内部で Storage を使うため、privatelink.blob.core.windows.net も VNet にリンクする必要があります。これを忘れると Profiler のデータがアップロードできません。
まとめ
- AMPLS = Workspace / Component を Private Link 経由にする束ね役。Workspace 単独の PE は存在しない
-
PrivateOnlyモードで public アクセスを scope 単位 で強制拒否できる ("weakest link") - 必要な Private DNS Zone は 4 つ + Profiler 使うなら blob 追加
- AMPLS 自体のアクセスログは取れない、Portal は PrivateOnly でも見える、
azCLI にバグあり、構築順序に注意 - Bicep API version は
2021-07-01-preview以降必須
閉域化案件ではほぼ確実に登場するリソースなので、最初に概念を整理しておくと後がスムーズです。
参考