External Access Integrationは、SnowflakeのUDF・ストアドプロシージャ・Streamlitアプリの コード内から外部のHTTPSエンドポイントへ直接アクセスするための機能です。 従来はExternal Function(API Gateway経由)でしか外部通信できませんでしたが、 この機能によりPython/JavaのHTTPライブラリ(requests, urllib等)を使った直接通信が可能になります。
UDF / Stored Procedure / Streamlit
│
├─ EXTERNAL_ACCESS_INTEGRATIONS = (my_eai) ← 関数定義で指定
│
└─ External Access Integration (my_eai)
│
├─ ALLOWED_NETWORK_RULES = (rule_1, rule_2) ← 通信先制御
│ └─ Network Rule (rule_1)
│ ├─ TYPE = HOST_PORT
│ └─ VALUE_LIST = ('api.openai.com:443')
│
└─ ALLOWED_AUTHENTICATION_SECRETS = (api_key_secret) ← 認証情報
└─ Secret (api_key_secret)
└─ TYPE = GENERIC_STRING / OAUTH2 / PASSWORD-- 外部ホストへのアクセスを許可するNetwork Rule
CREATE OR REPLACE NETWORK RULE openai_rule
MODE = EGRESS
TYPE = HOST_PORT
VALUE_LIST = ('api.openai.com:443');
-- 複数ホストを許可する場合
CREATE OR REPLACE NETWORK RULE multi_api_rule
MODE = EGRESS
TYPE = HOST_PORT
VALUE_LIST = (
'api.openai.com:443',
'api.anthropic.com:443',
'hooks.slack.com:443'
);Network RuleのMODEはEGRESS(送信方向)を指定します。 TYPEはHOST_PORTでホスト名とポートの組み合わせを許可します。 HTTPSの場合はポート443を指定します。
-- Generic String型のSecret(APIキー)
CREATE OR REPLACE SECRET openai_api_key
TYPE = GENERIC_STRING
SECRET_STRING = 'sk-proj-xxxxxxxxxxxxxxxxxxxx';
-- OAuth2型のSecret(トークン自動リフレッシュ)
CREATE OR REPLACE SECRET salesforce_oauth
TYPE = OAUTH2
API_AUTHENTICATION = salesforce_security_integration
OAUTH_REFRESH_TOKEN = 'xxxxxxxx';
-- Password型のSecret(Basic認証)
CREATE OR REPLACE SECRET basic_auth_secret
TYPE = PASSWORD
USERNAME = 'api_user'
PASSWORD = 'secure_password_123';-- External Access Integrationの作成
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION openai_eai
ALLOWED_NETWORK_RULES = (openai_rule)
ALLOWED_AUTHENTICATION_SECRETS = (openai_api_key)
ENABLED = TRUE;
-- 複数のNetwork RuleとSecretを組み合わせる場合
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION multi_api_eai
ALLOWED_NETWORK_RULES = (multi_api_rule)
ALLOWED_AUTHENTICATION_SECRETS = (openai_api_key, slack_webhook_secret)
ENABLED = TRUE;-- Python UDFから外部APIを呼び出す
CREATE OR REPLACE FUNCTION call_openai_chat(prompt VARCHAR)
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = '3.10'
PACKAGES = ('requests')
HANDLER = 'run'
EXTERNAL_ACCESS_INTEGRATIONS = (openai_eai)
SECRETS = ('api_key' = openai_api_key)
AS $
import requests
import _snowflake
def run(prompt):
api_key = _snowflake.get_generic_secret_string('api_key')
response = requests.post(
'https://api.openai.com/v1/chat/completions',
headers={
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
},
json={
'model': 'gpt-4o-mini',
'messages': [{'role': 'user', 'content': prompt}],
'max_tokens': 500
},
timeout=30
)
response.raise_for_status()
return response.json()['choices'][0]['message']['content']
$;
-- UDFの呼び出し
SELECT call_openai_chat('Snowflakeとは何ですか?30文字で説明してください。');-- Slack通知プロシージャ
CREATE OR REPLACE PROCEDURE send_slack_alert(message VARCHAR)
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = '3.10'
PACKAGES = ('requests')
HANDLER = 'run'
EXECUTE AS CALLER
EXTERNAL_ACCESS_INTEGRATIONS = (multi_api_eai)
SECRETS = ('webhook_url' = slack_webhook_secret)
AS $
import requests
import _snowflake
def run(session, message):
webhook_url = _snowflake.get_generic_secret_string('webhook_url')
response = requests.post(
webhook_url,
json={'text': f':warning: Snowflake Alert: {message}'},
timeout=10
)
response.raise_for_status()
return f'Sent: {response.status_code}'
$;
CALL send_slack_alert('ETLパイプラインが失敗しました');| Secret TYPE | 用途 | コード内での取得関数 |
|---|---|---|
| GENERIC_STRING | APIキー、トークン、Webhook URL | _snowflake.get_generic_secret_string() |
| OAUTH2 | OAuthアクセストークン(自動リフレッシュ) | _snowflake.get_oauth_access_token() |
| PASSWORD | Basic認証のユーザー名/パスワード | _snowflake.get_username_password() |
| 観点 | External Function | External Access Integration |
|---|---|---|
| 通信経路 | API Gateway経由 | UDF/プロシージャから直接HTTPS |
| プロキシサーバー | クラウドのAPI Gateway必須 | 不要 |
| 認証設定 | API Integration(IAMロール等) | Network Rule + Secret |
| 対応言語 | SQL関数として利用 | Python / Java / Scala |
| ユースケース | 既存API Gatewayとの統合 | 新規の外部API直接呼び出し |
| 操作 | 必要な権限 |
|---|---|
| CREATE NETWORK RULE | スキーマに対するCREATE NETWORK RULE権限 |
| CREATE SECRET | スキーマに対するCREATE SECRET権限 |
| CREATE EXTERNAL ACCESS INTEGRATION | CREATE INTEGRATION権限(ACCOUNTADMIN推奨) |
| UDFでのEAI利用 | EAIに対するUSAGE + Secretに対するUSAGE権限 |
Security & Integrations
問題 1
Python UDFから外部のREST APIに直接HTTPSリクエストを送信したい。API Gateway(AWS Lambda等)は使用しない前提で、最低限作成が必要なオブジェクトの組み合わせとして正しいものはどれか。
正解: B
API Gatewayを経由せずUDFから直接外部APIを呼び出すにはExternal Access Integrationを使用します。EAIの作成にはALLOWED_NETWORK_RULESの指定が必須であるため、先にNetwork Ruleを作成する必要があります。認証情報が必要な場合はさらにSecretも作成します。API IntegrationはExternal Function(API Gateway経由)の場合に使用するオブジェクトです。
External Access IntegrationとAPI Integrationの違いは何ですか?
API IntegrationはExternal Functionがクラウドプロバイダーの API Gatewayを経由して外部APIを呼び出すための認証設定です。一方External Access IntegrationはUDF/プロシージャ内のコード(Python, Java等)から直接HTTPリクエストを送信するための、ネットワークレベルのアクセス許可設定です。API IntegrationはAPI Gateway経由の間接呼び出し、External Access Integrationは関数コードからの直接呼び出しという点で異なります。
Network Ruleで許可するホスト名にワイルドカードは使えますか?
VALUE_LISTに指定するホスト名にはワイルドカード(*.example.com等)は使用できません。完全修飾ドメイン名(FQDN)を個別に列挙する必要があります。複数のサブドメインにアクセスが必要な場合は、各サブドメインをVALUE_LISTに明示的に追加します。これはセキュリティ上の意図的な制約で、許可先を厳密に管理するための設計です。
External Access Integrationを使うUDFで秘密情報(APIキー等)を安全に管理する方法は?
SnowflakeのSecret(CREATE SECRET)を使用します。SecretにAPIキーやOAuthトークンを格納し、External Access IntegrationのALLOWED_AUTHENTICATION_SECRETSで参照を許可します。UDFのコード内では_snowflake.get_generic_secret_string()(Python)でSecretの値を取得でき、APIキーをコード内にハードコードする必要がなくなります。Secretへのアクセス権限はRBACで制御されます。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Snowflake資格一覧|全11試験(SnowPro)の難易度・費用
Snowflake認定資格(SnowPro)全11試験の一覧・難易度・費用・出題範囲を徹底解説。...
Snowflake試験の難易度ランキング|全11資格を徹底比較
Snowflake(SnowPro)認定全11試験の難易度をランキング形式で比較。学習時間・合格に必要なスキルから分析。...
Snowflake資格の勉強方法|効率的な学習ルートと合格のコツ
Snowflake認定資格(SnowPro)に最短で合格するための勉強方法。公式リソース・学習スケジュールを徹底ガイド。...
SnowPro Core試験完全解説|出題範囲・問題例・合格戦略
SnowPro Core Certification(COF-C03)を徹底解説。出題範囲・100問の試験形式・合格ライ...
SnowPro Platform Associate完全解説|入門試験の攻略
SnowPro Associate: Platform Certification(SOL-C01)を徹底解説。最も簡単...