
Azure Data FactoryからSnowflakeへのManaged Private Endpointを設定してデータ連携してみた
かわばたです。
Azure Data Factory(ADF)からSnowflakeへデータを連携する際、デフォルトではpublic endpoint(パブリックエンドポイント)経由での接続となります。以下の記事では、public endpoint経由でBlob Storage内のCSVをSnowflakeにロードする手順を紹介しました。
セキュリティ要件が厳しい環境では、Private Linkによりprivate endpoint(プライベートエンドポイント)経由の接続経路を用意し、必要に応じてネットワークポリシーなどでpublic endpoint経由の接続を制限する構成が求められます。
本記事では、ADFのManaged Private EndpointとSnowflakeのOutbound Private Connectivityを組み合わせて、これら3経路すべてをPrivate Link経由で構成し、Blob Storage内のCSVをSnowflakeにロードするまでの手順と確認結果をまとめます。
技術的アプローチ
ADFのManaged Virtual NetworkとManaged Private Endpoint、およびSnowflakeのOutbound Private Connectivityを組み合わせて、データロード経路全体をPrivate Link経由で構成します。
- 経路1(ADF → Snowflake): ADFのManaged Private EndpointからSnowflakeのAzure Private Link Service経由で接続します
- 経路2(ADF → Blob Storage): ADFのManaged Private EndpointからBlob Storageに接続し、ソースCSVの読み取りやステージングBlobへの一時ファイル書き込みを行います
- 経路3(Snowflake → Blob Storage): SnowflakeのOutbound Private Connectivityを使い、COPY INTO実行時にADFが配置したステージングBlob上の一時ファイルを読み取ります
この構成により、対象のデータ転送経路はPrivate Link経由となり、Microsoftのバックボーンネットワーク内で通信できます。
制限事項
- SnowflakeのAzure Private Link(インバウンド・アウトバウンドとも)はBusiness Critical以上のエディションが必要です
SYSTEM$GET_PRIVATELINK_CONFIG()でprivatelink-pls-idを取得できますが、ADF Managed Private Endpoint作成時に利用できない場合はSnowflakeサポートにエンドポイントサービスリソースIDを確認します- ADF/SynapseなどのManaged Private Endpointは、Snowflakeの通常のセルフサービス承認フローではサポートされないため、Snowflakeサポートへの依頼が必要です
コスト
Azure Private Linkのコストとして、料金ページ上は主に以下の課金項目があります(Japan Eastリージョン、2026年5月8日時点。実際の料金は契約・通貨・為替・表示条件により変わるため、必ず公式料金ページで確認してください)。
- Private Endpointの時間課金
- Private Endpoint経由の受信データ処理量
- Private Endpoint経由の送信データ処理量
検証環境
- Snowflake: Microsoft Azure Japan Eastリージョン、Business Criticalエディション
- 必要なSnowflakeロール: ACCOUNTADMINロール
- Azure Data Factory: Managed Virtual Networkが有効化された状態で作成済み
- Azure Blob Storage: CSVファイル格納用およびステージング用。Public network accessをDisabledに設定
- Azure権限: ADFでManaged Private Endpointを作成できる権限、Storage AccountでPrivate Endpoint connectionを承認できる権限
事前準備
エンドポイントサービスリソースIDの確認
Snowflake公式ドキュメント上は、SYSTEM$GET_PRIVATELINK_CONFIG()の戻り値にprivatelink-pls-idが含まれます。ただし、Snowflake Community記事ではこの関数がPrivate Linkエイリアスのみを返すケースがあるとされており、その場合はSnowflakeサポートにエンドポイントサービスリソースIDを問い合わせる必要があります。
※かわばたも下記フォーマットで出力されなかったため、Snowflakeサポートへ問い合わせました。
ターゲット リソース IDのフォーマット
/subscriptions/<subscriptionID>/resourceGroups/<resourceGroupName>/providers/Microsoft.Network/privateLinkServices/<resourceName>

Snowflake Private Link設定情報の取得
SnowflakeでACCOUNTADMINロールを使用し、Private Link設定情報を取得します。
USE ROLE ACCOUNTADMIN;
SELECT key, value::VARCHAR
FROM TABLE(FLATTEN(INPUT => PARSE_JSON(SYSTEM$GET_PRIVATELINK_CONFIG())));
以下の値を控えておきます。これらはADFでManaged Private Endpoint作成時のFQDN(Fully Qualified Domain Name)として設定します。
privatelink-account-urlregionless-privatelink-account-urlprivatelink-ocsp-url

Blob Storageの準備
ソースCSVの格納先およびステージング用のAzure Blob Storageを準備します。
- Storage Accountを作成し、コンテナーを作成します
- ソースCSVファイルをコンテナーにアップロードします
- Public network accessを
Disabledに設定します(Azureポータル > Storage Account >ネットワーク)


Snowflakeのデータベース・テーブル準備
Snowflakeにロード先のデータベース、スキーマ、テーブル、ウェアハウスを作成します。また、ADF実行用のロールを作成し、必要な権限を付与します。
-- データベースとスキーマの作成
USE ROLE SYSADMIN;
-- データベースの作成
CREATE DATABASE IF NOT EXISTS ADF_DEMO_DB;
-- スキーマの作成
CREATE SCHEMA IF NOT EXISTS ADF_DEMO_DB.RAW;
-- テーブルの作成
CREATE TABLE IF NOT EXISTS ADF_DEMO_DB.RAW.RAW_CUSTOMERS (
ID VARCHAR,
NAME VARCHAR
);
CREATE WAREHOUSE IF NOT EXISTS ADF_DEMO_WH
WAREHOUSE_SIZE = XSMALL
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED = TRUE;
-- ADF実行用ロールの作成と権限付与
USE ROLE SECURITYADMIN;
CREATE ROLE IF NOT EXISTS ADF_ROLE;
GRANT ROLE ADF_ROLE TO USER <ADF用ユーザー名>;
USE ROLE SYSADMIN;
-- ウェアハウスの利用権限
GRANT USAGE ON WAREHOUSE ADF_DEMO_WH TO ROLE ADF_ROLE;
-- データベース・スキーマへのアクセス権限
GRANT USAGE ON DATABASE ADF_DEMO_DB TO ROLE ADF_ROLE;
GRANT USAGE ON SCHEMA ADF_DEMO_DB.RAW TO ROLE ADF_ROLE;
-- テーブルへの読み書き権限
GRANT SELECT, INSERT ON TABLE ADF_DEMO_DB.RAW.RAW_CUSTOMERS TO ROLE ADF_ROLE;
-- ステージの作成・削除権限(Copy Activityが内部的に使用)
GRANT CREATE STAGE ON SCHEMA ADF_DEMO_DB.RAW TO ROLE ADF_ROLE;
Azure Data Factoryの準備
ADFがManaged Virtual Networkを有効にした状態で作成されていることを確認します。
今回はAzure Integration Runtime側でManaged Virtual Networkを有効化しています。


試してみた
ADFでManaged Private Endpointを作成
ADF StudioでManage→Managed private endpoints→Newを選択します。

検索画面でプライベートリンクサービスを選択します。

アカウントの選択方法をEnter manuallyにチェックボックスを入れます。
以下の情報を入力します。
- ターゲット リソース ID:
エンドポイントサービスリソースIDの確認でSnowflakeサポートから受領したエンドポイントサービスリソースID - 完全修飾ドメイン名:
SYSTEM$GET_PRIVATELINK_CONFIG()またはSYSTEM$ALLOWLIST_PRIVATELINK()で取得したPrivate Link用のホスト名をそのまま指定しますprivatelink-account-urlの値(アカウントロケーターのPrivate Link URL)regionless-privatelink-account-urlの値(リージョンレスアカウントのPrivate Link URL)privatelink-ocsp-urlの値(OCSPエンドポイントのPrivate Link URL)- 必要に応じて
regionless-privatelink-ocsp-urlの値(リージョンレスOCSPエンドポイントのPrivate Link URL)

作成後、ステータスがPendingになっていることを確認します。

Managed Private EndpointリソースIDの取得
作成したManaged Private Endpointの名前をクリックし、Managed private endpoint resource IDを取得します。この値は次のステップでSnowflakeサポートに提供します。

Snowflakeサポートへの接続承認依頼
Snowflakeサポートに再度連絡し、以下の情報を提供して接続の承認を依頼します。
- ADF Managed Private Endpoint Resource ID: 前のステップで取得した値
- Managed Private Endpoint name:Managed Private Endpointの名称
サポートが承認すると、ADF Studio上でManaged Private EndpointのステータスがApprovedに変わります。

ADFでBlob Storage向けManaged Private Endpointを作成
ADF → Blob Storageの経路をPrivate化するため、Blob Storage用のManaged Private Endpointを作成します。
ADF StudioでManage→Managed private endpoints→Newを選択します。
接続先としてAzure Blob Storageを選択します。

以下の情報を入力します。
- Azure subscription: 対象のサブスクリプション
- Storage account name: CSVファイルが格納されているStorage Account

作成後、AzureポータルでStorage Accountのネットワーク→プライベート エンドポイント接続を開き、ADFから作成されたPrivate Endpoint connectionを**承認(Approve)**します。

ADF Studio側でManaged Private EndpointのステータスがApprovedに変わったことを確認します。

Snowflake → Blob StorageのOutbound Private Connectivity設定
Snowflake側からBlob Storageへのアクセス経路をPrivate化するため、SnowflakeのOutbound Private Connectivityを設定します。
SnowflakeでACCOUNTADMINロールを使用し、SYSTEM$PROVISION_PRIVATELINK_ENDPOINTを実行してBlob Storage向けのPrivate Endpointをプロビジョニングします。
USE ROLE ACCOUNTADMIN;
SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
'<ストレージアカウントのリソースID>',
'<storage-account-name>.blob.core.windows.net',
'blob'
);

プロビジョニング後、AzureポータルでStorage Accountのネットワーク→プライベート エンドポイント接続を開き、Snowflakeから作成されたPrivate Endpoint connectionを**承認(Approve)**します。

Snowflake側でエンドポイントの状態を確認します。
SELECT SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO();

Storage Integrationの作成
SnowflakeがBlob Storageにアクセスするための認可設定として、Storage Integrationを作成します。**USE_PRIVATELINK_ENDPOINT = TRUE**を設定することで、Private Link経由でのアクセスとなります。
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE STORAGE INTEGRATION outbound_private_link_int
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'AZURE'
ENABLED = TRUE
AZURE_TENANT_ID = '<tenant-id>'
STORAGE_ALLOWED_LOCATIONS = ('azure://<storage-account-name>.blob.core.windows.net/<container-name>/')
USE_PRIVATELINK_ENDPOINT = TRUE;
Storage Integrationの情報を確認し、Snowflakeサービスプリンシパルの情報を取得します。
DESC STORAGE INTEGRATION outbound_private_link_int;

出力から以下の値を控えます。
AZURE_CONSENT_URL: ブラウザでアクセスしてSnowflakeサービスプリンシパルへの同意を付与しますAZURE_MULTI_TENANT_APP_NAME: サービスプリンシパルのアプリケーション名
AZURE_CONSENT_URLにアクセスして同意を付与した後、AzureポータルでStorage Accountのアクセス制御 (IAM)からSnowflakeのサービスプリンシパルにStorage Blob Data Readerロールを付与します。
GRANT USAGE ON INTEGRATION outbound_private_link_int TO ROLE ADF_ROLE;
Integration Runtimeの設定
接続テストの前に、ADFのIntegration RuntimeでInteractive authoringを有効化します。
ADF Studioの左メニューからManage→Integration runtimesを選択し、AutoResolveIntegrationRuntimeをクリックします。
ポップアップウィンドウでVirtual networkタブに移動し、Interactive authoringをEnabledに設定してApplyをクリックします。

Linked Serviceの作成と接続テスト
ADF Studioの左メニューからManage→Linked services→Newを選択します。
検索バーで「Snowflake」を検索し、Snowflakeコネクタを選択してContinueをクリックします。

Snowflakeの接続情報を入力します。Private Link用のSnowflakeホスト名が使われるように設定することが重要です。ADFのSnowflake V2コネクタでは、UIやバージョンによってaccount identifierとhostのフィールド構成が異なります。account identifierのみの場合は末尾に.privatelinkを含めた値を指定し、hostフィールドがある場合は*.privatelink.snowflakecomputing.com形式のFQDNを指定します。
{account-locator}.{region-id}.privatelink

Blob Storage Linked Serviceの作成
ADF StudioでManage→Linked services→Newを選択し、Azure Blob Storageを選択します。

- Account selection method: Azure subscriptionから選択
- Storage account name: 対象のStorage Account
Test connectionをクリックし、「Connection successful」と表示されればOKです。

データセット・パイプラインの作成とデータロード実行
Blob Storage内のCSVをSnowflakeにロードするパイプラインを作成します。
ソースデータセットの作成
ADF StudioのAuthorタブでDatasets→New datasetを選択し、Azure Blob StorageのDelimitedTextを選択します。

以下を設定します。
- Linked service: 前のステップで作成したBlob Storage Linked Service
- File path: CSVファイルが格納されているコンテナー/フォルダー/ファイル名
- First row as header: 有効化(CSVにヘッダー行がある場合)

シンクデータセットの作成
Datasets→New datasetを選択し、Snowflake(Snowflake V2コネクタ)を選択します。
以下を設定します。
- Linked service: 前のステップで作成したSnowflake Linked Service
- Table: ロード先テーブル(例:
ADF_DB.ADF_SCHEMA.TARGET_TABLE)

パイプラインの作成
Pipelines→New pipelineを選択し、Copy dataアクティビティをドラッグ&ドロップします。
Sourceタブでソースデータセットを選択します。

Sinkタブでシンクデータセットを選択します。
Settingsタブで以下を設定します。
- Enable staging: チェックを入れる
- Staging account linked service: Blob Storage Linked Serviceを選択
- Storage path: ステージング用のコンテナー名(例:
staging) - Storage integration: 作成したStorage Integration名(例:
outbound_private_link_int)

パイプラインのデバッグ実行
パイプラインのDebugをクリックして実行します。
実行がSucceededになることを確認します。

Snowflake側でのデータ確認
Snowflakeでロード先テーブルのデータを確認します。
SELECT COUNT(*) FROM ADF_DEMO_DB.RAW.RAW_CUSTOMERS;

ソースCSVの件数と一致していればデータロード成功です。
ネットワークポリシーの設定
Snowflake側にネットワークポリシーが設定されている場合、ADFのManaged VNetのCIDRを許可する必要があります。Microsoftのトラブルシューティングでも、Managed Private Endpointを利用しSnowflake側でネットワークポリシーを使っている場合は、Managed VNet CIDRを許可する必要があると案内されています。
ADFのManaged VNetでは10.0.0.0/8の範囲を許可する例が紹介されていますが、これは非常に広い範囲です。
-- 注意:
-- SET ALLOWED_IP_LIST は既存の許可リストを指定内容で再設定(上書き)します。
-- 既存の許可IP/CIDRを漏らさないよう、事前に現在の設定を確認してください。
ALTER NETWORK POLICY my_network_policy
SET ALLOWED_IP_LIST = (
'既存の許可IPまたはCIDR',
'10.0.0.0/8'
);
補足: ソースデータがAzure SQL Databaseの場合
本記事ではBlob Storage上のCSVをソースとしていますが、実際の運用ではAzure SQL Databaseなどのデータベースからデータを抽出してBlob Storageに配置し、そこからSnowflakeにロードするケースもあります。
この場合、ADF → Azure SQL Databaseの経路も別途Private化が必要です。具体的には以下の追加設定が必要になります。
- ADF Managed Private Endpoint to Azure SQL Database(Sub-resource:
sqlServer)を作成 - Azure SQL Database側の
ネットワーク→プライベート エンドポイント接続でPrivate Endpoint connectionを承認 - Azure SQL Database側でPublic network accessを制限している場合は、Private Endpoint経由のみでアクセスする構成とする
つまり、Azure SQL Database → Blob Storage → Snowflakeという構成で全経路をPrivate化する場合は、最大で以下の4つのPrivate Endpoint/Connectivityが必要になります。
| 経路 | 必要な設定 |
|---|---|
| ADF → Azure SQL Database | ADF Managed Private Endpoint(Sub-resource: sqlServer) |
| ADF → Blob Storage | ADF Managed Private Endpoint(Sub-resource: blob) |
| ADF → Snowflake | ADF Managed Private Endpoint(Snowflake Private Link Service) |
| Snowflake → Blob Storage | Snowflake Outbound Private Connectivity |
最後に
Azure Data FactoryからBlob Storage内のCSVをSnowflakeにロードするまでの全経路をPrivate Link経由で構成し、パブリックインターネットを経由しないデータロードパイプラインを構築する手順を確認しました。
ポイントをまとめると以下の通りです。
- Blob StorageのPublic network accessを無効化する構成では、ADF→Snowflake、ADF→Blob Storage、Snowflake→Blob Storageの3経路をPrivate Link経由にする必要があります。
- Snowflakeサポートへの問い合わせが必要です。
- Managed Private Endpoint作成時には、Private Link用のFQDN(アカウントロケーター、リージョンレスアカウント名、OCSP。必要に応じてリージョンレスOCSP)を登録する必要があります。
- Snowflake Linked Serviceでは、Private Link用のホスト名(
.privatelinkを含むもの)を使用する必要があります。UIによってはaccount identifierに.privatelinkを含める方式、またはhost欄にPrivate Link用FQDNを指定する方式があります。 - Storage Integrationには**
USE_PRIVATELINK_ENDPOINT = TRUEを設定**し、Snowflake→Blob Storage間もPrivate Link経由にする必要があります。
セキュリティ要件としてプライベート接続が求められる環境でADFとSnowflakeを連携する場合は、この構成に加えてSnowflake側のネットワークポリシーなどを組み合わせることでより堅牢な構成にできます。設定箇所は多いですが、各経路を分けて考えることで整理しやすくなります。Snowflakeサポートとのやり取りが必要な点はスケジュール面で考慮が必要だと感じました。
この記事が何かの参考になれば幸いです!







