
Azure Data FactoryのData Flow から Snowflake へ Private Link 経由でロードしてみた
かわばたです。
本記事では、前回のパブリック通信構成をベースに、Azure Data Factory の Mapping Data Flow Activity から Snowflake へ Private Link 経由でロードする完全閉域構成を検証します。
【前回記事(パブリック通信版)】
【Azure Data FactoryからSnowflakeへのManaged Private Endpointを設定してデータ連携】
背景・課題
前回の記事では、Azure SQL Database を Source、ADF Mapping Data Flow を変換・ロード処理、Snowflake を Sink として、Snowflake internal data transfer を利用したロード構成を確認しました。
構成は以下でした。
Azure SQL Database
Table
↓ Public endpoint
Azure Data Factory
Mapping Data Flow Activity
↓ Public endpoint
Snowflake
Database / Schema / Table
前回はパブリック通信経由で検証しましたが、実運用では以下のような要件が出ることがあります。
- Snowflake への接続を Private Link 経由にしたい
- Snowflake internal stage への通信もパブリックインターネットを経由させたくない
- Azure SQL Database への通信も閉域にしたい
- ADF Managed Virtual Network / Managed Private Endpoint を使って完全閉域通信にしたい
- Copy Activity ではなく Data Flow Activity のまま Private Link 化したい
そこで今回は、既存の Data Flow 構成をベースに、ADF Data Flow 実行基盤からの通信経路を Private Link 経由にする構成を検証します。
技術的アプローチ
構成図
ADF Managed VNet
Mapping Data Flow Activity
├─ Managed Private Endpoint (sqlServer)
│ └─ Azure SQL Database
│
├─ Managed Private Endpoint (Azure Private Link Service)
│ └─ Snowflake account endpoint
│
└─ Managed Private Endpoint (blob)
└─ Snowflake internal stage 用 Azure Storage
Private Link化する3つの通信経路
今回のポイントは、Private Link化する対象が3つあります。
1. ADF Data Flow 実行基盤 → Azure SQL Database
2. ADF Data Flow 実行基盤 → Snowflake account endpoint
3. ADF Data Flow 実行基盤 → Snowflake internal stage 用 Azure Storage
ADF Managed Virtual Network では、Managed Private Endpoint を使って Private Link 対応リソースに接続できます。Managed Private Endpoint は Data Factory の Managed VNet 内に作成される Private Endpoint であり、承認済み状態のものだけが対象リソースに通信できます。
今回のポイント
| 項目 | 方針 |
|---|---|
| ADF Activity | Mapping Data Flow Activity |
| Source | Azure SQL Database |
| Sink | Snowflake Table |
| Snowflake Connector | Snowflake V2 Connector |
| IR | Managed Virtual Network enabled Azure Integration Runtime |
| Azure SQL Database 接続 | ADF Managed Private Endpoint (sqlServer) |
| Snowflake account 接続 | ADF Managed Private Endpoint |
| Snowflake internal stage 接続 | ADF Managed Private Endpoint (blob) |
| Snowflake 認証 | Key pair 認証 |
| ステージング | Snowflake internal data transfer / internal stage |
| Storage Integration | 使用しない |
注意点
今回の検証では、ADF Managed Private Endpoint を Snowflake internal stage 用 Azure Storage に対して作成します。
Snowflake の公式ドキュメントでは、Azure Private Endpoint と Azure Private Link を使うことで、Snowflake internal stage への data loading / unloading を Azure 内部ネットワーク経由にできると説明されています。
Snowflake account endpoint への Azure Private Link 接続についても、Snowflake 公式ドキュメントのセルフサービス手順(SYSTEM$AUTHORIZE_PRIVATELINK() を使用)は ADF / Synapse などの Managed Private Endpoint の認可をサポートしていない旨が記載されています。Snowflake Support への確認が必要です。
制限事項
- Snowflake の Azure private endpoints for internal stages は Business Critical 以上の Edition が必要です
- Snowflake 公式ドキュメントの Azure Private Link セルフサービス手順については、ADF / Synapse などの Managed Private Endpoint の認可をサポートしていません。Snowflake Support への確認が必要です
- ADF Managed Virtual Network では Custom DNS がサポートされません。通常の VNet + Private DNS Zone 構成とは挙動が異なります
- Mapping Data Flow は Spark クラスター上で実行されるため、起動コスト(ウォームアップ時間)があります
前提条件
以下が作成済みであることを前提とします。
Azure 側
- Azure Data Factory
- Azure SQL Database / 検証用テーブル(
dbo.test_snow) - ADF Mapping Data Flow(Source: Azure SQL Database、Sink: Snowflake)
- Azure SQL Database Linked Service
- Snowflake V2 Linked Service
- Source / Sink Dataset
- Pipeline
- 前回記事のパブリック通信構成で Data Flow が正常終了していること
Snowflake 側
- Snowflake Account(Business Critical 以上)
- ADF 接続用 User / Role
- Key pair 認証設定
- Load 先 Database / Schema / Warehouse / Table
事前準備
ADF Managed Virtual Network 対応 Azure IR を作成する
ADF Studio を開きます。
Manage
→ Integration runtimes
→ New
→ Azure, Self-Hosted
→ Azure

以下のように設定します。
| 項目 | 設定値 |
|---|---|
| Name | 任意の名前。例: AzureIR-ManagedVNet |
| Type | Azure |
| Region | ADF と同一リージョン推奨 |
| Virtual network configuration | Enable |
| Managed Virtual Network | Enabled |
| Data flow runtime | 必要に応じて General / Memory optimized などを選択 |
| Core count | 検証用途なら小さめで可 |
| Time to live | 検証用途なら 0 または短め |

Snowflake 側で Private Link 情報を取得する
Snowflake 側で Private Link 構成情報を取得します。
USE ROLE ACCOUNTADMIN;
SELECT
KEY,
VALUE
FROM TABLE(
FLATTEN(
INPUT => PARSE_JSON(SYSTEM$GET_PRIVATELINK_CONFIG())
)
);
取得した情報のうち、以下のキーを控えておきます。
| Snowflake config key | 用途 |
|---|---|
privatelink-pls-id |
Azure Private Link Service の alias / Managed Private Endpoint の接続先 |
privatelink-account-url |
Snowflake account 接続用 FQDN |
regionless-privatelink-account-url |
regionless account URL を使う場合の FQDN |
privatelink-ocsp-url / regionless-privatelink-ocsp-url |
OCSP 用 FQDN |
Snowflake internal stage 用 Private Link を有効化する
次に、Snowflake internal stage 用 Private Link を有効化します。
USE ROLE ACCOUNTADMIN;
ALTER ACCOUNT SET ENABLE_INTERNAL_STAGES_PRIVATELINK = TRUE;
続いて、internal stage 用 Azure Storage Account の Resource ID を取得します。
SELECT
KEY,
VALUE
FROM TABLE(
FLATTEN(
INPUT => PARSE_JSON(SYSTEM$GET_PRIVATELINK_CONFIG())
)
)
WHERE KEY = 'privatelink-internal-stage';

privatelink-internal-stage の値に、Snowflake が管理する internal stage 用 Azure Storage Account の情報が含まれます。
取得する情報の例です。
{
"ResourceID": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxx/providers/Microsoft.Storage/storageAccounts/xxxx",
"Endpoint": "xxxx.blob.core.windows.net"
}
以降の手順では、以下を使います。
| 値 | 用途 |
|---|---|
| ResourceID | ADF Managed Private Endpoint の target resource |
| Storage Account 名 | FQDN 設定 |
| blob | Target sub-resource / groupId |
試してみた
ADF から Azure SQL Database への Managed Private Endpoint を作成する
完全閉域構成のため、まず Azure SQL Database 向けの Managed Private Endpoint を作成します。
ADF Studio で以下を開きます。
Manage
→ Managed private endpoints
→ New
Azure SQL Database を検索し、選択します。

| 項目 | 設定値 |
|---|---|
| Name | mpe-azuresql-db |
| Azure subscription | 対象の Subscription |
| Server name | Azure SQL Server 名 |
| Target sub-resource / groupId | sqlServer |
作成後、Managed Private Endpoint は Pending 状態になります。
Azure Portal で SQL Server リソースを開き、Networking → Private endpoint connections から、作成した Private Endpoint 接続を 承認(Approve) します。

承認後、ADF Studio で Managed Private Endpoint のステータスが Approved に変わることを確認します。
Azure SQL Database の Public network access を無効化する
完全閉域構成にするため、Azure SQL Server の Public network access を無効化します。
- Azure Portal で SQL Server リソースを開く
Networkingを選択Public network accessをDisabledに設定Saveをクリック

ADF から Snowflake account endpoint への Managed Private Endpoint を作成する
次に、Snowflake account endpoint 向けの Managed Private Endpoint を作成します。
下記記事の通り対応しました。
ADF Studio 側では、対応する Managed Private Endpoint のステータスが Approved であることも合わせて確認します。
ADF から Snowflake internal stage 用 Azure Storage への Managed Private Endpoint を作成する
次に、Snowflake internal stage 用 Azure Storage Account に対して Managed Private Endpoint を作成します。
ADF Studio で以下を開きます。
Manage
→ Managed private endpoints
→ New

Azure Blob Storage または Azure Storage を選択し、Snowflake から取得した internal stage 用 Storage Account の Resource ID を指定します。
| 項目 | 設定値 |
|---|---|
| Name | mpe-snowflake-internal-stage-blob |
| Target resource ID | privatelink-internal-stage の ResourceID |
| Target sub-resource / groupId | blob |

Snowflake 公式ドキュメントでも、Azure 側で Private Endpoint を作成する際に Target sub-resource が blob であることを確認するよう記載されています。
Snowflake 側で internal stage 用 Private Endpoint を承認する
ADF Managed Private Endpoint を作成すると、接続は Pending 状態になります。
ADF Managed Private Endpoint の Resource ID を控えます。
/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.DataFactory/factories/<adf-name>/managedVirtualNetworks/default/managedPrivateEndpoints/mpe-snowflake-internal-stage-blob
Snowflake 側で以下を実行します。
USE ROLE ACCOUNTADMIN;
SELECT SYSTEM$AUTHORIZE_STAGE_PRIVATELINK_ACCESS(
'<ADF Managed Private Endpoint Resource ID>'
);
承認状況を確認します。
USE ROLE ACCOUNTADMIN;
SELECT SYSTEM$GET_STAGE_PRIVATELINK_AUTHORIZED_ENDPOINTS();

Linked Service の Integration Runtime を変更する
Private Link 経由にするため、以下の Linked Service を Managed VNet enabled Azure IR に変更します。
Azure SQL Database Linked Service
| 項目 | 設定値 |
|---|---|
| Name | 既存のもの |
| Connect via integration runtime | AzureIR-ManagedVNet |
| Authentication type | 既存と同じ |
| Server name | 既存と同じ |
| Database name | 既存と同じ |
Snowflake V2 Linked Service
| 項目 | 設定値 |
|---|---|
| Name | 既存のもの |
| Connect via integration runtime | AzureIR-ManagedVNet |
| Account identifier | Private Link 用 account identifier |
| Database | ADF_DEMO_DB |
| Warehouse | ADF_DEMO_WH |
| Role | ADF_ROLE |
| Authentication type | KeyPair |
| User | ADF_USER |
| Private key | 既存と同じ |
Test connection を実行し、Succeeded と表示されることを確認します。
Data Flow を Debug 実行する
既存の Data Flow を開きます。
Author
→ Data flows
→ 対象 Data Flow
Source と Sink は既存記事と同じです。
Source:
Azure SQL Database Dataset
Sink:
Snowflake Dataset
Pipeline 側の Data Flow Activity で、Integration Runtime が AzureIR-ManagedVNet になっていることを確認します。
その後、Debug 実行します。

確認ポイントは以下です。
- Azure SQL Database からデータを読み取れること
- Snowflake account endpoint に接続できること
- Snowflake internal stage を利用した internal data transfer 処理が成功すること
- Snowflake table にロードされること
- Query History に COPY INTO が記録されること
Snowflake 側でロード結果と Query History を確認する
Snowflake 側で件数を確認します。
SELECT *
FROM test_snow
LIMIT 10;

データが正しくロードされていれば問題ありません。
完全閉域チェック
サポート回答でも指摘されている通り、構成情報のみを根拠に「完全にクローズドな通信経路である」と判断するのではなく、デプロイ後に実際の通信経路を検証することが重要です。
ここでは、完全閉域であることを確認するための手順を順に実施します。
Snowflake internal stage の public access をブロックする
Private Link 経由で internal stage に到達できることを確認した後、internal stage の public access をブロックします。
USE ROLE ACCOUNTADMIN;
SELECT SYSTEM$BLOCK_INTERNAL_STAGES_PUBLIC_ACCESS();
ステータスを確認します。
SELECT SYSTEM$INTERNAL_STAGES_PUBLIC_ACCESS_STATUS();

【参考ブログ】
public access ブロック後に ADF Data Flow を再実行する
public access ブロック後、再度 ADF Data Flow を実行します。


| 結果 | 意味 | 対処 |
|---|---|---|
| 成功 | ADF Data Flow → Snowflake internal stage の通信が Private Link 経由で成立している | 閉域構成が正常に機能している |
| 失敗(internal stage 関連エラー) | Snowflake internal stage への通信が Private Link 経由になっていない | MPE の承認状態、SYSTEM$AUTHORIZE_STAGE_PRIVATELINK_ACCESS の承認状態を再確認 |
| 失敗(Snowflake 接続エラー) | Snowflake account endpoint への接続に問題がある | Snowflake account 向け MPE の状態を確認 |
Snowflake LOGIN_HISTORYで確認する
ADF接続ユーザーのPrivate Link利用状況を確認します。
-- ADF接続ユーザーのPrivate Link利用状況を確認
SELECT EVENT_TIMESTAMP, EVENT_TYPE, USER_NAME, CLIENT_IP,
REPORTED_CLIENT_TYPE, FIRST_AUTHENTICATION_FACTOR,
CLIENT_PRIVATE_LINK_ID
FROM SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY
WHERE USER_NAME = '<ADF接続ユーザー名>'
ORDER BY EVENT_TIMESTAMP DESC
LIMIT 10;

ADF接続ユーザーがPrivate Link経由で接続できていることが確認できました。
最後に
今回の検証では、既存の Azure SQL Database → ADF Mapping Data Flow → Snowflake の構成をベースに、ADF Data Flow 実行基盤からの通信経路を Private Link 経由にする構成を試しました。
Data Flow Activity の Snowflake Sink は Copy Activity と異なり、明示的な Azure Blob Storage ステージングではなく Snowflake internal data transfer を利用します。そのため、Private Link 化する場合も、外部ステージ用 Blob Storage ではなく、Snowflake internal stage 用 Azure Storage への Private Endpoint が重要になります。
この記事が何かの参考になれば幸いです!
参照リンク
- Microsoft Learn: Snowflake V2 connector
- Microsoft Learn: ADF Managed Virtual Network / Managed Private Endpoint
- Microsoft Learn: ADF Managed Private Endpoint ARM reference
- Snowflake Docs: Azure Private Link
- Snowflake Docs: SYSTEM$GET_PRIVATELINK_CONFIG
- Snowflake Docs: Azure private endpoints for internal stages
- Snowflake Docs: SYSTEM$AUTHORIZE_STAGE_PRIVATELINK_ACCESS
- Snowflake Docs: SYSTEM$ALLOWLIST_PRIVATELINK
- Snowflake Docs: SnowCD
- 前回記事: Azure SQL Database から ADF Data Flow Activity を使って Snowflake にロードしてみた







