はじめに
Azure Storage や SQL Database などの PaaS サービスは、既定ではインターネット経由(パブリック IP)でアクセスする構成です。一方で、エンタープライズ環境やセキュリティ要件の高い案件では、インターネット経由のアクセスを遮断し、社内ネットワークからのみ接続させたいという要件が生じます。
本記事では、仮想ネットワーク(VNet)内の仮想マシンから、Private Endpoint(プライベートエンドポイント)を経由して、インターネットを通らずに Blob Storage へ接続する環境の構築手順を解説します。
- Private Endpoint を使用した Blob Storage への閉域接続の構成手順
- 閉域接続で要となる DNS(Private DNS Zone)の仕組みと確認方法
- Azure Bastion 経由での VM 操作と、閉域環境でのファイル準備の進め方
結論として、閉域接続の成否は DNS の名前解決に集約されます。接続先の FQDN(mystorage.blob.core.windows.net)自体は変わらず、Private DNS Zone によって返す IP アドレスをプライベート IP へ差し替えることで、通信が Azure バックボーン内に閉じます。接続できない場合の多くは、この DNS 統合または VNet リンクの設定に起因します。
構成概要と仕組み
設定に入る前に、今回構築する環境と、Private Endpoint を理解するうえで要となる DNS の仕組みを整理します。
検証構成
今回は以下の構成を作成します。クライアントとなる仮想マシン(VM)はパブリック IP を持たず、インターネットから隔離されています。VM から Storage へのアクセスは、Private Endpoint を介して Azure のバックボーンネットワークのみを通ります。

Private Endpoint とは
Private Endpoint は、Azure の PaaS サービス(Storage、SQL Database など)に対して、自分の VNet 内のプライベート IP アドレスを割り当てる機能です。
- 通常(パブリックエンドポイント): インターネット上のパブリック IP アドレスに対してアクセスします。
- Private Endpoint: VNet 内の
10.0.0.5のようなプライベート IP アドレスに対してアクセスします。
これにより、VNet 内のリソースと同様に、プライベート IP アドレスを用いて PaaS サービスへ接続できます。
DNS の重要性(仕組み)
Private Endpoint を導入する際、最も注意したいのが DNS 設定です。ここが正しく構成されていないと、Private Endpoint を作成しても接続できません。
理由は名前解決にあります。Private Endpoint を有効にしても、接続先の URL(FQDN)は mystorage.blob.core.windows.net のまま変わりません。クライアント(VM)がこの URL を通常のパブリック DNS で解決すると、パブリック IP が返り、Private Endpoint を経由しません。
そこで、この FQDN をプライベート IP(10.x.x.x)へ解決させるための Private DNS Zone(VNet 内の名前解決用ゾーン)が必要になります。Azure は、Private Endpoint 作成時に CNAME レコードを privatelink サブドメインへ向け、Private DNS Zone 側の A レコードでプライベート IP を返す形で名前解決を成立させます。
参考: Use private endpoints – Azure Storage(Microsoft Learn)
“the DNS CNAME resource record for the storage account is updated to an alias”
(プライベートエンドポイント作成時、ストレージアカウントの DNS CNAME レコードがprivatelinkプレフィックスのエイリアスへ更新される)
https://learn.microsoft.com/en-us/azure/storage/common/storage-private-endpoints
名前解決の経路をパブリックと閉域で対比すると、次のようになります。

本手順では、この DNS 統合も含めて設定を行います。
検証用リソースの作成(VM / Bastion)
まずは、検証の土台となる仮想ネットワークと、クライアント役の仮想マシン、そこへ安全に接続するための踏み台(Azure Bastion)を作成します。
1. 仮想ネットワーク(VNet)の作成
- Azure Portal 上部の検索バーで「仮想ネットワーク」を検索し、[作成] をクリックします。
- [基本] タブで以下を入力します。
- リソースグループ: 新規作成(例:
rg-private-link-test) - 名前: 任意の VNet 名(例:
vnet-test) - 地域: 任意のリージョン(例: Japan East)
- リソースグループ: 新規作成(例:
- [IP アドレス] タブへ進みます。
- デフォルトのアドレス空間(
10.0.0.0/16)で問題ありません。 - デフォルトのサブネット(
default)があることを確認します。 - Bastion 用のサブネットを追加します。
- [サブネットの追加] をクリックし、以下を設定します。
- 名前:
AzureBastionSubnet(この名前は固定です) - アドレス範囲:
10.0.1.0/26(Bastion の専用サブネットは/26以上が必要です)
- デフォルトのアドレス空間(
- [レビューと作成] をクリックして作成します。

2. Azure Bastion のデプロイ
ブラウザー経由で VM に RDP 接続するための Bastion を作成します。
Azure Bastion には Developer・Basic・Standard・Premium の 4 つの SKU があります。本手順では、専用サブネットを用いたシンプルな構成として Basic を使用します。ファイル転送機能は Standard 以上で提供されるため、本記事では Bastion のファイル転送は使わず、後述のとおり VM 内で直接ダウンロードする方法をとります。単一 VM の検証用途であれば、無償の Developer SKU も選択肢になります(対応リージョンが限定され、同時接続は 1 VM まで)。
参考: What is Azure Bastion?(Microsoft Learn)
“advanced features (native client, shareable links, IP-based connections, custom ports, file transfer)”
(ネイティブクライアント、共有可能リンク、IP ベース接続、カスタムポート、ファイル転送などの高度な機能は Standard 以上で提供される)
https://learn.microsoft.com/en-us/azure/bastion/bastion-overview
- 検索バーで「Bastion」を検索し、[作成] をクリックします。
- 以下を設定します。
- 名前: 任意の名前(例:
bas-test) - 地域: VNet と同じリージョン
- 仮想ネットワーク: 作成した vnet-test を選択(自動的に AzureBastionSubnet が選ばれます)
- レベル(SKU): Basic を選択
- 名前: 任意の名前(例:
- [確認と作成] をクリックしてデプロイします。
- デプロイには時間がかかります(環境により十数分程度)。完了を待つ間に、次の VM 作成へ進めます。

3. 仮想マシン(VM)の作成
検証用のクライアント端末を作成します。インターネットからの直接アクセスを遮断するため、パブリック IP は付与しません。
- 検索バーで「仮想マシン」を検索し、[作成] > [Azure 仮想マシン] を選択します。
- [基本] タブ:
- 仮想マシン名: 任意の名前(例: vm-client)
- セキュリティの種類: Standard
- イメージ: Windows Server 2022 Datacenter など
- 管理者アカウント: ログイン用のユーザー名とパスワードを設定
- [ネットワーク] タブ:
- 仮想ネットワーク: vnet-test
- サブネット: default
- パブリック IP:「なし(None)」を選択(この VM はインターネットから直接到達できなくなり、閉域化されます)
- [確認と作成] をクリックして作成します。

これで、インターネットから隔離された閉域 VM と、そこへ接続するための入り口(Bastion)の準備が整いました。
ストレージアカウントの作成
接続先となる Azure Storage を作成し、テスト用ファイルをアップロードするためのコンテナーを準備します。
1. ストレージアカウントの作成
- 検索バーで「ストレージ アカウント」を検索し、[作成] をクリックします。
- [基本] タブで以下を設定します。
- リソースグループ: 作成済みのグループ(例: rg-private-link-test)
- ストレージアカウント名: 全世界で一意の名前(例: stprivatelinktest2026)
- 地域: VNet と同じリージョン(例: Japan East)
- 冗長性: 検証用途のため、ローカル冗長ストレージ(LRS)で十分です。
- [ネットワーク] タブで、パブリックネットワークアクセスを「無効」に設定します。
- これにより、インターネットからのアクセスを最初から遮断します。この時点ではどこからも接続できない状態になります。
- [確認] > [作成] をクリックしてデプロイします。

2. コンテナーの作成
- 作成したストレージアカウントのリソース画面へ移動します。
- 左メニューの [データ ストレージ] > [コンテナー] をクリックします。
- 上部の [+ コンテナー] をクリックします。
- 以下を設定して [作成] をクリックします。
- 名前: 任意の名前(例: test-container)
- パブリックアクセスレベル:「プライベート(匿名アクセスなし)」

これで、接続先となるストレージと、ファイルの格納場所が準備できました。
Private Endpoint の作成と DNS 設定
ストレージアカウントに対して Private Endpoint を作成し、VNet 内のプライベート IP を割り当てます。
1. 作成ウィザードの開始
接続先リソース(今回は Storage)の画面から作成すると、設定が自動入力されるため簡単です。
- 作成したストレージアカウント(
stprivatelinktest...)の画面を開きます。 - 左メニューの [セキュリティ + ネットワーク] > [ネットワーク] をクリックします。
- [プライベート エンドポイント接続] タブを開き、[+ プライベート エンドポイント] をクリックします。

2. 基本設定とリソース指定
- [基本] タブ:
- リソースグループ: rg-private-link-test
- 名前: 任意の名前(例: pe-storage-blob)
- 地域: VNet と同じリージョン
- [リソース] タブ:
- 対象サブリソース:「blob」を選択します。
fileやtableを選ぶと Blob コンテナーへ接続できないため注意してください。
- 対象サブリソース:「blob」を選択します。

3. 仮想ネットワークとサブネット
- [仮想ネットワーク] タブ:
- 仮想ネットワーク: 作成済みの
vnet-testを選択 - サブネット:
defaultを選択(Bastion 用のAzureBastionSubnetは選びません)
- 仮想ネットワーク: 作成済みの
4. DNS 統合設定
VNet 内からドメイン名でアクセスした際に、プライベート IP が返るように設定します。
- [DNS] タブへ進みます。
- プライベート DNS ゾーンと統合する:「はい(Yes)」が選択されていることを確認します。
- プライベート DNS ゾーン:(新規)
privatelink.blob.core.windows.netとなっていることを確認します。
ここを「はい」にすると、Azure が次の処理を自動で行います。
- Private DNS Zone の作成:
privatelink.blob.core.windows.netという名前解決用ゾーンを作成。 - A レコードの登録: ストレージ名とプライベート IP(例:
10.0.0.5)の紐づけを登録。 - VNet リンク: 作成した DNS ゾーンを VNet に紐づけ。

5. 作成の完了
- [確認と作成] をクリックして設定を完了します。
- デプロイ完了後、作成された Private Endpoint のリソースへ移動し、[DNS 構成] メニューを確認します。
- 割り当てられた IP アドレス(例:
10.0.0.4や10.0.0.5)が表示されていれば設定完了です。

6. VNet リンクの確認(トラブルシューティング)
作成ウィザードで自動設定されますが、まれに VNet との紐づけ(リンク)が登録されないことがあります。念のため確認します。
- 作成された Private DNS ゾーン(
privatelink.blob.core.windows.net)を開きます。 - 左メニューの [仮想ネットワーク リンク] をクリックします。
- 今回の VNet(
vnet-test)が一覧にあるか確認します。なければ [+ 追加] から手動で VNet を追加します。

このリンクがないと、VM から名前解決ができず接続に失敗します。自動で登録されない主な要因は次のとおりです。
- 同名の DNS ゾーンを直前に削除した直後で、内部のメタデータが残っているケース。
- Private Endpoint 本体と DNS 設定が個別に処理されるため、タイミングによってリンク登録だけがタイムアウトするケース。
動作確認: ツールの準備と閉域接続
環境構築が完了しました。VM にログインし、ツールをインストールして接続を確認します。
1. ツールの準備(VM 内でダウンロード)
- Azure Portal から Bastion 経由で VM にログインします。
- VM 内でブラウザー(Microsoft Edge)を起動します。
- 「Azure Storage Explorer」で検索し、公式サイトからインストーラー(
StorageExplorer-windows-x64)をダウンロードしてインストールします。

VM からはインターネットへのアウトバウンド通信が可能なため、直接ダウンロードできます。
2. テスト用ファイルの作成
Blob Storage にアップロードするためのテストファイルを作成します。
- VM 内で PowerShell を起動します。
- 以下のコマンドを実行します。
# デスクトップに "testfile.txt" という名前で、現在時刻が入ったファイルを作成
$date = Get-Date
Set-Content -Path "$HOME\Desktop\testfile.txt" -Value "これは閉域網接続のテストです。作成日時: $date"デスクトップに testfile.txt が作成されていれば完了です。
3. 名前解決の確認(nslookup)
ツールを使う前に、正しい経路(Private Endpoint)を通っているかを確認します。これはトラブルシューティングにおいて重要な手順です。
- VM 内でコマンドプロンプト(
cmd)を起動します。 - 以下のコマンドを実行します。
nslookup <作成したストレージアカウント名>.blob.core.windows.net結果の Address に注目します。
- 成功:
10.0.0.5などのプライベート IP が返る。 - 失敗: グローバル IP が返る(DNS 設定を見直します)。
あわせて、TCP レベルの到達性も確認しておくと切り分けが確実になります。PowerShell で次のコマンドを実行します。
Test-NetConnection -ComputerName <ストレージアカウント名>.blob.core.windows.net -Port 443TcpTestSucceeded が True であれば、443 番ポートへの到達性が確認できます。なお、Private Endpoint は TCP と UDP のトラフィックに対応し、ICMP は対象外のため、ping では疎通確認できません。この制約の詳細は後述の「制約事項・設計上の注意」を参照してください。
4. アクセスキーの取得(Azure Portal)
- VM 内のブラウザーで Azure Portal を開きます。
- 作成したストレージアカウント(
stprivatelinktest...)の画面を開きます。 - 左メニューの [セキュリティ + ネットワーク] > [アクセス キー] をクリックします。
key1の [表示] ボタンを押し、[キー] の値をコピーして控えます。
本手順では簡便さのため、アカウントキー(共有キー)で接続します。運用環境では、より安全な Microsoft Entra ID 認証(マネージド ID 等)の利用も検討できます。
5. Storage Explorer での接続
- インストールした Azure Storage Explorer を起動します。
- 左側の [接続ダイアログを開く] アイコンをクリックします。
- [リソースの選択] 画面で「ストレージ アカウントまたはサービス」→「アカウント名とキー」を選択します。
- 以下を入力します。
- 表示名: 任意の名前(例:
Test-Connection) - アカウント名: 作成したストレージアカウント名
- アカウントキー: 手順 4 でコピーした
key1の値を貼り付け
- [次へ] > [接続] をクリックします。
6. ファイルのアップロード
- 左ツリーに接続したストレージが表示されるので、[Blob Containers] > [test-container] を開きます。
- デスクトップに作成した
testfile.txtを、画面右側のエリアにドラッグ&ドロップします。 - 転送状況エリアに「完了」と表示され、ファイル一覧に表示されれば成功です。

インターネットを経由せず、閉域網のみでファイルが転送されました。
制約事項・設計上の注意
Private Endpoint は手軽に閉域化できる一方、設計時に把握しておきたい制約がいくつかあります。導入前に確認しておくと、後段のトラブルを避けやすくなります。
疎通確認は ping ではなく TCP で行う
Private Endpoint が対応するのは TCP と UDP のトラフィックのみで、ICMP は対象外です。このため、ping や tracert では正しい経路や到達性を確認できません。疎通確認は、名前解決を見る nslookup と、TCP ポートを見る Test-NetConnection -Port 443 の組み合わせで行うことをおすすめします。
参考: Azure Private Link FAQ(Microsoft Learn)
“TCP and UDP traffic are only supported for a private endpoint.”
(プライベートエンドポイントで対応するのは TCP と UDP のトラフィックのみ)
https://learn.microsoft.com/en-us/azure/private-link/private-link-faq
PE サブネットでは NSG・UDR が既定で適用されない
Private Endpoint を配置したサブネットでは、ネットワークセキュリティグループ(NSG)やユーザー定義ルート(UDR)が既定では適用されません。適用するには、サブネットの privateEndpointNetworkPolicies を有効化します。Azure CLI では次のように設定します(二重否定の指定になる点に注意してください)。
# PE サブネットで NSG / ルートテーブルを有効化する
az network vnet subnet update \
--resource-group rg-private-link-test \
--vnet-name vnet-test \
--name default \
--disable-private-endpoint-network-policies falseポータルや ARM では、Disabled / NetworkSecurityGroupEnabled / RouteTableEnabled / Enabled の値で個別に制御できます。運用では、Private Endpoint は専用サブネットに配置し、他用途と混在させない構成が管理しやすくなります。
- システムルートがピアリング先にも伝播する
-
Private Endpoint を作成すると、その IP に対する
/32のシステムルートが自動生成され、ピアリング済みの VNet にも伝播します。意図しない経路が広がっていないか、ハブ&スポーク構成では設計時に確認しておくと安全です。 - パブリックアクセス無効化はデータプレーンの遮断
-
ストレージのパブリックネットワークアクセスを「無効」にすると、インターネットからのデータアクセス(データプレーン)が遮断されます。一方で、一部の管理プレーン操作や TCP ハンドシェイクは挙動が異なる場合があるため、ロックダウンの確認はポートチェックだけでなく、実際のデータアクセス(Storage Explorer での参照可否など)で行うことをおすすめします。
- 接続には privatelink サブドメインを直接使わない
-
接続には通常の FQDN(
stxxx.blob.core.windows.net)をそのまま使用します。privatelink.blob.core.windows.netのサブドメイン URL で直接接続する構成は推奨されていません。CNAME による名前解決でプライベート IP に到達する仕組みのため、接続文字列はパブリックエンドポイントと同じものを使えます(参照: https://learn.microsoft.com/en-us/azure/storage/common/storage-private-endpoints )
Private Endpoint と サービスエンドポイントの違い
PaaS への閉域・限定アクセスには、Private Endpoint のほかにサービスエンドポイント(VNet Service Endpoints)という選択肢もあります。両者は似て非なるもので、選定を誤ると要件を満たせないため、主な違いを整理します。
| 観点 | Private Endpoint | サービスエンドポイント |
|---|---|---|
| 接続先 IP | VNet 内のプライベート IP | サービスのパブリック IP のまま |
| DNS | Private DNS Zone が必要(FQDN をプライベート IP へ解決) | 変更不要(パブリック IP へ解決) |
| 適用範囲 | 特定リソース単位(粒度が細かい) | サブネット単位+サービス単位 |
| オンプレ・ピアリングからの利用 | 可(VPN・ExpressRoute・ピアリング経由) | 不可(VNet 内発の通信のみ) |
| 対応プロトコル | TCP・UDP | TCP のみ |
| 料金 | 時間課金+データ処理課金(有償) | 無償 |
| データ流出対策 | リソース単位で限定でき強固 | サブネットからサービス全体に開く |
選定の目安は次のとおりです。完全な閉域化、オンプレや他 VNet からの利用、リソース単位の制御が必要な場合は Private Endpoint が適します。VNet 内からの手軽なアクセス制限で十分で、コストを抑えたい場合はサービスエンドポイントが選択肢になります。Microsoft は PaaS への安全な接続では Private Endpoint の利用を推奨しています(参照: https://learn.microsoft.com/en-us/azure/private-link/private-link-faq )
Azure CLI でまとめて構築する手順
ここまでの GUI 手順と同じ構成を、Azure CLI で再現する例を示します。検証環境の再作成や IaC 化の出発点として活用できます。変数は環境に合わせて変更してください。各コマンドは公式リファレンスに準拠しています。
# 変数定義(環境に合わせて変更)
RG="rg-private-link-test"
LOC="japaneast"
VNET="vnet-test"
SUBNET="default"
STORAGE="stprivatelinktest2026"
PE_NAME="pe-storage-blob"
ZONE="privatelink.blob.core.windows.net"
# リソースグループ
az group create --name $RG --location $LOC
# VNet とサブネット
az network vnet create \
--resource-group $RG \
--name $VNET \
--address-prefixes 10.0.0.0/16 \
--subnet-name $SUBNET \
--subnet-prefixes 10.0.0.0/24
# ストレージアカウント(パブリックアクセス無効)
az storage account create \
--resource-group $RG \
--name $STORAGE \
--location $LOC \
--sku Standard_LRS \
--kind StorageV2 \
--public-network-access Disabled
# ストレージアカウントのリソース ID を取得
STORAGE_ID=$(az storage account show \
--resource-group $RG \
--name $STORAGE \
--query id \
--output tsv)
# Private Endpoint の作成(blob サブリソース)
az network private-endpoint create \
--resource-group $RG \
--name $PE_NAME \
--vnet-name $VNET \
--subnet $SUBNET \
--private-connection-resource-id $STORAGE_ID \
--group-id blob \
--connection-name "storage-blob-connection"
# Private DNS Zone の作成
az network private-dns zone create \
--resource-group $RG \
--name $ZONE
# DNS Zone を VNet にリンク
az network private-dns link vnet create \
--resource-group $RG \
--zone-name $ZONE \
--name "blob-dns-link" \
--virtual-network $VNET \
--registration-enabled false
# Private Endpoint の IP を DNS Zone へ自動登録
az network private-endpoint dns-zone-group create \
--resource-group $RG \
--endpoint-name $PE_NAME \
--name "blob-dns-zone-group" \
--private-dns-zone $ZONE \
--zone-name blob--group-id に blob を指定する点が、Blob Storage への接続の要です。Data Lake Storage Gen2 を併用する場合は、dfs サブリソースの Private Endpoint も別途作成します。公式の CLI クイックスタートとサブリソースの一覧は次を参照してください: https://learn.microsoft.com/en-us/azure/private-link/create-private-endpoint-cli
まとめ
本記事では、Private Endpoint を使用して、インターネットを経由せずに Azure Storage へ接続する手順を解説しました。要点は、PaaS サービスにプライベート IP を割り当て、その IP を DNS で名前解決させることに集約されます。接続トラブルの多くは DNS 統合と VNet リンクに起因するため、nslookup での確認を押さえておくと切り分けが容易になります。検証後は、課金を抑えるためにリソースグループごと削除しておくと安全です。
- Private Endpoint は PaaS にプライベート IP を割り当てる機能
- 接続先 FQDN は変えずに DNS の返す IP を切り替える。
- Private DNS Zone との統合で CNAME と A レコードを自動登録
- nslookup でプライベート IP が返れば経路は正しい。
- Private Endpoint は TCP と UDP に対応し ping は通らない。
- VNet リンクの未登録が名前解決失敗の主な要因
- 検証後はリソースグループごと削除して課金を抑える。
以上、最後までお読みいただきありがとうございました。
