このエントリは2025/02/15現在の情報に基づいています。将来の機能追加や変更に伴い、記載事項からの乖離が発生する発生があります。
2025/02/15現在、Azure API Management (APIM) のStandard v2でPrivate Endpointが限定Previewで利用できるようになっている(早くGAしてほしい、と思っている人も多いはず)。以下は執筆時点での注意点などをまとめたメモ。
受信プライベート エンドポイントを使用して API Management に非公開で接続する / Connect privately to API Management using an inbound private endpoint
https://learn.microsoft.com/azure/api-management/private-endpoint
Private Endpointを構成しただけでは、Internetからのアクセスを無効化できない
Private Endpointを構成した場合、当該サービスリソースへのアクセスはInternetからアクセスできない、というのが通例であるが、APIMの場合様相が異なる。外部・内部モードではないデプロイ(Standard v2の場合を含む)でInboundのPrivate Endpointを構成した場合、明示的に外部アクセスを拒否しない限り、Internetからアクセスできる。Private Endpointを構成すればInternetからのアクセスがブロックされる、というわけではない。Internetからのアクセスを無効化する方法は以下のドキュメントに記載がある。
パブリック ネットワーク アクセスを必要に応じて無効にする / Optionally disable public network access
https://learn.microsoft.com/azure/api-management/private-endpoint#optionally-disable-public-network-access
InternetからのトラフィックとVNetからのトラフィックは識別できる
どのPrivate Endpointを経由したかがわかるので、下図のように、必要に応じてInternetからのトラフィックとVNetからのトラフィックを別のバックエンドにルーティング(赤破線)したり、バックエンドを入れ替えたり(青破線)なんてことも可能。つまり、Application Gatewayにおける内部、外部向けリスナーの構成と同等のことができる(値段のことはここでは考慮しない)。

経由したPrivate Endpointの情報は context.Request.PrivateEndpointConnection で確認できる。この値がnullの場合、Internetからのアクセス。もしnullでない場合には、経由したPrivate Endpointの情報 (IPrivateEndpointConnection) が入る。実際に確認できるかどうかを試してみる。
試してみる
下図のようなトポロジーを考える。今回はAPIMはStandard V2を使ったが、STv2でも同じ。

context.Request.PrivateEndpointConnectionがnullであればInternet経由を表す”Over the Internet”を、そうでない場合はVNet経由なのでPrivate Endpointの名前を、それぞれ返すようなポリシーを作成する。
<policies>
<inbound>
<base />
...
<choose>
<!-- traffic from the Internet -->
<when condition="@(context.Request.PrivateEndpointConnection == null)">
<return-response>
<set-status code="200" reason="from the internet" />
<set-body>@("Over the Internet")</set-body>
</return-response>
</when>
<!-- traffic from VNet -->
<otherwise>
<return-response>
<set-status code="200" reason="from vnet" />
<set-body>@(context.Request.PrivateEndpointConnection.Name)</set-body>
</return-response>
</otherwise>
</choose>
...
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
仮想マシンからリクエストを投げ込んだ場合、Private Endpointを経由しているので、以下のような感じの応答が返る。
$ curl <APIのURL>
pe-apim-jpe
$
対してInternet経由の場合。
$ curl <APIのURL>
Over the Internet
$
これで何が実現できるか
VNet内外からのアクセスを受け付ける場合、STv2ではPremium SKUを使い、Application Gatewayを前段に配置した内部モードで構成する必要がある(どうしてもお財布に優しくない)。
| STv2 | Consumption | Basic | Standard | Premium (Developer) |
|---|---|---|---|---|
| Public->Public | ○ | ○ | ○ | ○ |
| Public->VNet | ○ | |||
| VNet->Public | ○ | ○ | ○ | |
| VNet->VNet | ○ | |||
| 備考 | Private Endpoint利用可 | Private Endpoint利用可 | Private Endpointは外部・内部モードデプロイ以外で利用可 |
| V2 | Basic | Standard | Premium (preview) |
|---|---|---|---|
| Public->Public | ○ | ○ | ○ |
| Public->VNet | ○ | ○ | |
| VNet->Public | ○ | ○ | |
| VNet->VNet | ○ | ○ | |
| 備考 | Private EndpointとVNet統合利用可 | VNet InjectionもしくはVNet統合を利用可(現時点では、VNet InjectionとVNet統合を共存できない) |
Standard V2でPrivate EndpointがGAすれば、Publicアクセス、VNetからのアクセスを識別しながら、1個のAPIMでVNet内外からのアクセスを問わずに両方のトラフィックを捌くことが出来、しかもお財布に優しい。もちろんキャパシティの制限を考慮しながらではあるが、構成の自由度が高くなるので、コストを意識したSKU選択ができそう(個人的には、デプロイ時間が大幅に短縮されるのがうれしい)。