はじめに
Microsof Fabricでは Managed private endpoint を使用して様々なPrivate IPを持つリソースにアクセスできるが、対応しているAzureのリソースID 以外に対してはPrivate Link serviceを使用して背後にAzure Load Balancerや仮想マシンを配備してIP転送する必要があった。これは以前試した Azure Synapse Spark Poolからオンプレミスのリソースにアクセスする の記事ではFabricではないがその構成を試したものと同じ話。
現在Public PreviewのPrivate Link service Direct ConnectはこのようなAzure Load Balancerや仮想マシンを必要とせず、プライベートにルーティング可能な任意の宛先IPアドレスに直接接続できるようにするというものだ。これを使えば複雑な構成から解放されてシンプルにできるのではないかということで早速試してみた。
構成の概要
オンプレミスのデータソースを準備するのが大変なので、今回はテスト用としてAzure OpenAIのPrivate Endpointを用意して、そこにPrivate Link service Direct Connect経由で接続する疑似構成とした。実際にはAzure OpenAIのPrivate Endpointに対しては、Private Link serviceを使用する必要は無く、Fabric Workspace上でManaged Private Endpointを作成するときにリソースIDを指定するだけで接続は可能なので、本来はAOAIに対してはこの手順を踏む必要は無い。ただ、方法としては接続先としてManaged Private Endpointがあて先として対応していないデータソースなどに置き換えればOK。
- 簡素化させるためにPrivate Link serviceとAzure OpenAIのPrivate Endpointは同一VNET内に配置し、サブネットは分けた。
- VNET(plsdcvnet)内の、Azure OpenAIのPriavte Endpointのsubnet(pesubnet)は10.0.0.0/24、Private Link serviceのsubnet(plssubnet)は10.0.1.0/24とした。
- 対象のFabric workspaceはOutboundのアクセスをブロックし、Managed Private Endpoint経由のみ外部にアクセスできるように構成。
- Azure OpenAIにはAI Foundry portalから適当なBase modelをデプロイして、Notebookから疎通できるかだけを簡易的にテスト。
設定
各種リソースのデプロイ
- リソースグループ、VNET、Azure OpenAI(+ Private Endpoint)は事前にデプロイする。
- Azure OpenAIがデプロイできたら、テスト用に何か一つBaseのモデルをデプロイしておく。
- Microsoft Fabricは有料のFabric容量でもいいし、試用版でもいいはず。
Private Link service Direct Connectの作成
作成自体は このドキュメント の通りに実行すればOK。現在のところAzure PortalからGUIで作成できないので、PowerShellとかAzure CLIを使う必要がある。
# 変数の設定
resourceGroupName="plstest"
location="westus3"
vnetName="plsdcvnet"
subnetName="plssubnet"
plsName="pls-directconnect "
destinationIP="10.0.0.4" # AOAIのPrivate IPを確認して設定
# Private Link serviceのsubnet上でのネットワークポリシーを無効化する
az network vnet subnet update --resource-group $resourceGroupName --vnet-name $vnetName --name $subnetName --private-link-service-network-policies Disabled
# Private Link service Direct Connectを作成する(IPは2つ必要となる)
az network private-link-service create --resource-group $resourceGroupName --name $plsName --destination-ip-address $destinationIP --location $location --ip-configurations '[
{
"name": "ipconfig1",
"primary": true,
"private-ip-allocation-method": "Static",
"private-ip-address": "10.0.1.10",
"subnet": {
"id": "/subscriptions/{サブスクリプションID}/resourceGroups/'$resourceGroupName'/providers/Microsoft.Network/virtualNetworks/'$vnetName'/subnets/'$subnetName'"
}
},
{
"name": "ipconfig2",
"primary": false,
"private-ip-allocation-method": "Static",
"private-ip-address": "10.0.1.11",
"subnet": {
"id": "/subscriptions/{サブスクリプションID}/resourceGroups/'$resourceGroupName'/providers/Microsoft.Network/virtualNetworks/'$vnetName'/subnets/'$subnetName'"
}
}
]'
作成後、Azure portalから作成したPrivate Link serviceを探して、ステータスが以下のようになっていればたぶんOK

Fabric workspaceにManaged Private Endpointをデプロイ
Fabricの設定にはManaged Private Endpointをデプロイするための画面が用意されているが、ここからPrivate Link serviceにリンクしたものをデプロイしようとするとエラーになってしまうため、今のところFabricのREST APIを使う必要があるようだ。利用するツールはPOSTMANとかみたいなクライアントでもいいし、curlコマンドでもいい。
認証トークンを取得する
REST APIをコールするために最初にBearer tokenを取得する。応答のなかから accessToken フィールド内の値をメモしておく
az login
az account get-access-token --resource https://api.fabric.microsoft.com
取得したトークンをもとにリクエストは以下のように構成できる。今回はcurlコマンドを使用している。
token="{取得したトークン}"
curl -X POST "https://api.fabric.microsoft.com/v1/workspaces/{対象のWorkspace ID/managedPrivateEndpoints" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $token" \
-d '{"name": "private-endpoint","targetPrivateLinkResourceId": "/subscriptions/{AzureサブスクリプションID}/resourceGroups/plstest/providers/Microsoft.Network/privateLinkServices/pls-directconnect","targetFQDNs": ["{AOAIのデプロイ名}.privatelink.openai.azure.com"],"requestMessage": "Private connection request from Fabric to AOAI Private Endpoint"}'
Private Endpoint接続要求を承認する
上記設定すると接続要求がPrivate Link serviceに届いているはずなので、以下の手順で要求を承認する。
- Azure portalにサインイン。
- Private Link serviceリソースに移動。
- [ネットワーク]セクションで[プライベート エンドポイント接続] を選択。
- 保留中の接続要求をMicrosoft Fabricから確認。
- [承認]を選択し、必要に応じて正当な理由を指定。
Fabric workspaceでOutboundをブロックする
該当のworkspaceでworkspace設定を開き、[Outbound networking]メニューからOutbound access protection設定があるので、ここから[Block outbound public access]をOnにする。

Outbound publicアクセスをブロックする場合にこのような警告が出てくる。制限かけられるのはこれらだけですよということなので、これをよく理解しておく。

これが有効化できない状態になっている場合は、テナント設定でルールが許可されてない可能性があるので、管理ポータルから以下の設定を探して設定する(管理者にしてもらう)必要がある。

接続テスト
Managed Private Endpointを設定したFabric workspaceでNotebookを立ち上げ以下のようにテストコードを記述。今回 requests を使ったがお好きな方法でやればOK。また、SSL証明書の警告がでてきて対処がよくわからなかったので疎通確認最優先で無効化して強引に実施しており、全然よくないコードなので注意。
import requests
import json
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# --- 設定 ---
resource_name = "{AOAIのリソース名}"
deployment_name = "o4-mini" # 事前にモデルはデプロイしておく。今回はo4-miniをデプロイ
api_key = "AOAIのAPI Key"
# Private Endpoint の FQDN
endpoint = f"https://{resource_name}.privatelink.openai.azure.com"
# Chat Completions API の URL
url = f"{endpoint}/openai/deployments/{deployment_name}/chat/completions?api-version=2025-01-01-preview"
headers = {
"Content-Type": "application/json",
"api-key": api_key
}
payload = {
"messages": [
{"role": "user", "content": "Hello via Private Endpoint from Fabric Notebook!"}
],
"max_completion_tokens": 50
}
# API コール
response = requests.post(url, headers=headers, json=payload, verify=False)
print("Status Code:", response.status_code)
print(response.json())
応答例
Status Code: 200
{'choices': [{'content_filter_results': {}, 'finish_reason': 'length', 'index': 0, 'logprobs': None, 'message': {'annotations': [], 'content': '', 'refusal': None, 'role': 'assistant'}}], 'created': 1763472863, 'id': 'chatcmpl-CdG8dyZLmKPFUbMLRNUNrG9p6285U', 'model': 'o4-mini-2025-04-16', 'object': 'chat.completion', 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'jailbreak': {'filtered': False, 'detected': False}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}], 'system_fingerprint': None, 'usage': {'completion_tokens': 50, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 50, 'rejected_prediction_tokens': 0}, 'prompt_tokens': 14, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}, 'total_tokens': 64}}
まとめ
今回はこの手順を踏む必要のないAzure OpenAIのPrivate Endpointに対してPrivate Link service Direct Connectを経由してアクセスする構成を取ったが、結果としては、これを例えばオンプレミスのリソースとか仮想マシンにたてたなんらかのデータベースなどにアクセスしたいときに、比較的シンプルな構成で接続できるということが分かった。GUIでの設定方法は今後対応されると思うので、とても期待している機能の一つだ。
