Storage Integrationは、Snowflakeが外部クラウドストレージ(S3・Azure Blob・GCS)へ アクセスする際の認証を一元管理するオブジェクトです。 ステージ定義にアクセスキーやシークレットを埋め込む代わりに、 クラウドプロバイダ側のIAMロールやサービスプリンシパルへのアクセス委任を設定することで、 長期鍵の配布・管理が不要になります。
Storage Integrationを作成すると、Snowflakeは内部的にクラウドプロバイダ固有のサービスアカウント (AWSの場合はIAMユーザーARN)を生成します。 このサービスアカウントに対してクラウド側でロールの引き受け(Assume Role)を許可する Trust Policyを設定することで、Snowflakeが安全にストレージへアクセスできるようになります。
| 概念 | 説明 |
|---|---|
| Storage Integration | Snowflakeアカウントレベルの認証オブジェクト |
| STORAGE_ALLOWED_LOCATIONS | アクセスを許可するクラウドストレージパスのリスト |
| STORAGE_BLOCKED_LOCATIONS | allowed内でもアクセスを拒否するパスのリスト |
| External Stage | Storage Integrationを参照するステージ定義 |
| DESCRIBE INTEGRATION | Snowflakeが生成したIAM ARN / External IDの確認コマンド |
┌──────────────────────┐
│ Snowflake │
│ Storage Integration │
│ (STORAGE_AWS_IAM_ │
│ USER_ARN を保持) │
└────────┬─────────────┘
│ 1. Assume Role リクエスト
│ (External ID を付与)
▼
┌──────────────────────┐
│ AWS IAM Role │
│ (Trust Policy で │
│ Snowflake ARN + │
│ External ID を許可)│
└────────┬─────────────┘
│ 2. 一時クレデンシャル発行
▼
┌──────────────────────┐
│ S3 Bucket │
│ /orders/ │
│ (IAM Roleの権限で │
│ 読み取り/書き込み) │
└──────────────────────┘-- AWS S3用 Storage Integration
CREATE OR REPLACE STORAGE INTEGRATION s3_orders_int
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'S3'
ENABLED = TRUE
STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/snowflake-access-role'
STORAGE_ALLOWED_LOCATIONS = (
's3://company-data-lake/orders/',
's3://company-data-lake/returns/'
)
STORAGE_BLOCKED_LOCATIONS = (
's3://company-data-lake/orders/secrets/'
);-- Azure Blob Storage用 Storage Integration
CREATE OR REPLACE STORAGE INTEGRATION azure_data_int
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'AZURE'
ENABLED = TRUE
AZURE_TENANT_ID = 'a]1b2c3d4-e5f6-7890-abcd-ef1234567890'
STORAGE_ALLOWED_LOCATIONS = (
'azure://myaccount.blob.core.windows.net/data-container/input/'
);-- Google Cloud Storage用 Storage Integration
CREATE OR REPLACE STORAGE INTEGRATION gcs_analytics_int
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'GCS'
ENABLED = TRUE
STORAGE_ALLOWED_LOCATIONS = (
'gcs://analytics-bucket/raw/',
'gcs://analytics-bucket/processed/'
);Storage Integration作成後、DESCRIBE INTEGRATIONでSnowflakeが生成した サービスアカウント情報を取得します。この値をクラウド側のTrust Policyに設定します。
DESC INTEGRATION s3_orders_int;
-- 主要な出力項目(AWSの場合)
-- ┌─────────────────────────────┬──────────────────────────────────────┐
-- │ property │ property_value │
-- ├─────────────────────────────┼──────────────────────────────────────┤
-- │ STORAGE_AWS_IAM_USER_ARN │ arn:aws:iam::987654321098:user/abc123│
-- │ STORAGE_AWS_EXTERNAL_ID │ ABC123_SFCRole=2_dGVzdA== │
-- │ STORAGE_ALLOWED_LOCATIONS │ s3://company-data-lake/orders/,... │
-- │ STORAGE_BLOCKED_LOCATIONS │ s3://company-data-lake/orders/sec... │
-- └─────────────────────────────┴──────────────────────────────────────┘DESCRIBE INTEGRATIONで取得したSTORAGE_AWS_IAM_USER_ARNとSTORAGE_AWS_EXTERNAL_IDを AWS側のIAMロールのTrust Policyに設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::987654321098:user/abc123"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "ABC123_SFCRole=2_dGVzdA=="
}
}
}
]
}IAMロールにはS3バケットへのGetObject / ListBucket(読み取り)、 必要に応じてPutObject / DeleteObject(書き込み)の権限を付与します。
-- Storage Integrationを参照するExternal Stage
CREATE OR REPLACE STAGE ext_orders_stage
URL = 's3://company-data-lake/orders/'
STORAGE_INTEGRATION = s3_orders_int
FILE_FORMAT = (TYPE = 'PARQUET');
-- ステージ上のファイル確認
LIST @ext_orders_stage;
-- データロード
COPY INTO ORDERS
FROM @ext_orders_stage
PATTERN = '.*\.parquet'
ON_ERROR = 'CONTINUE';
-- データアンロード
COPY INTO @ext_orders_stage/export/
FROM ORDERS
FILE_FORMAT = (TYPE = 'PARQUET')
HEADER = TRUE;| 観点 | 直接認証(鍵埋め込み) | Storage Integration |
|---|---|---|
| セキュリティ | 低い(平文鍵がステージ定義に露出) | 高い(IAMロール委任、鍵なし) |
| 鍵管理 | 手動ローテーション必要 | 一時クレデンシャル自動発行 |
| 鍵ローテーション | ステージ再作成が必要 | 不要(クラウド側のみ管理) |
| アクセス範囲 | 鍵の権限に依存 | ALLOWED/BLOCKED_LOCATIONSで制御 |
| 複数ステージの共有 | 各ステージに鍵を設定 | 1つのIntegrationを複数ステージで共有 |
| 推奨度 | 非推奨(レガシー) | 推奨(公式ベストプラクティス) |
| 操作 | 必要な権限 | 対象ロール |
|---|---|---|
| CREATE INTEGRATION | CREATE INTEGRATION(アカウントレベル) | ACCOUNTADMIN または委任ロール |
| ALTER / DROP INTEGRATION | OWNERSHIP ON INTEGRATION | Integration所有ロール |
| ステージで参照 | USAGE ON INTEGRATION | ステージ作成ロール |
| DESCRIBE INTEGRATION | USAGE ON INTEGRATION | 設定確認者 |
-- 権限付与の例
-- ACCOUNTADMINがIntegrationを作成
USE ROLE ACCOUNTADMIN;
CREATE STORAGE INTEGRATION s3_orders_int ...;
-- データエンジニアロールにUSAGE権限を付与
GRANT USAGE ON INTEGRATION s3_orders_int TO ROLE DATA_ENGINEER;
-- DATA_ENGINEERがステージを作成
USE ROLE DATA_ENGINEER;
CREATE STAGE ext_orders
URL = 's3://company-data-lake/orders/'
STORAGE_INTEGRATION = s3_orders_int;| エラー / 症状 | 原因 | 対処 |
|---|---|---|
| Failure using stage area. Cause: Access Denied | IAMロールのTrust PolicyにSnowflakeのARNが未設定 | DESC INTEGRATIONのSTORAGE_AWS_IAM_USER_ARNをTrust Policyに設定 |
| External ID mismatch | Trust PolicyのExternalIdがDESC出力と不一致 | STORAGE_AWS_EXTERNAL_IDを正確にコピーして再設定 |
| Insufficient privileges on integration | ステージ作成ロールにUSAGE権限なし | GRANT USAGE ON INTEGRATION ... TO ROLE ... |
| ListBucket Access Denied | IAMポリシーにs3:ListBucket権限なし | IAMポリシーにListBucket権限を追加(Resource: バケットARN) |
| KMS Access Denied | SSE-KMS暗号化バケットでKMS権限不足 | IAMポリシーにkms:Decrypt / kms:GenerateDataKeyを追加 |
| 指定パスにファイルが見えない | STORAGE_ALLOWED_LOCATIONSとステージURLのパスが不一致 | URLがALLOWED_LOCATIONSのプレフィックス範囲内か確認 |
Architect / Data Engineer
問題 1
あるチームがS3上のParquetファイルをSnowflakeにロードするためにExternal Stageを作成しました。CREATE STAGE文でSTORAGE_INTEGRATIONパラメータを指定しています。しかしLIST @stageを実行すると「Access Denied」エラーが発生します。Storage IntegrationのDESCRIBE結果は正常に取得できています。最も可能性の高い原因はどれですか?
正解: A
DESCRIBE INTEGRATIONが正常に取得できていることから、Snowflake側のIntegration設定自体は正しいことがわかります。Access DeniedエラーはAWS側の権限問題を示しており、最も一般的な原因はIAMロールのTrust PolicyにSnowflakeのサービスアカウント(STORAGE_AWS_IAM_USER_ARN)とExternalId(STORAGE_AWS_EXTERNAL_ID)が正しく設定されていないことです。BのFILE_FORMATはデータ解析時のエラーであり、LIST(ファイル一覧取得)では影響しません。CのウェアハウスはLISTコマンドには必要ですが、エラーメッセージが「Access Denied」であることからウェアハウスの問題ではありません。DのBLOCKED_LOCATIONSにバケット全体を指定するとIntegration作成時にエラーになるため、この時点では発生しません。
Storage IntegrationなしでExternal Stageを作成することは可能ですか?
技術的にはAWS_KEY_IDとAWS_SECRET_KEYを直接指定してExternal Stageを作成できます。しかしクレデンシャルがステージ定義に平文で埋め込まれるため、SHOW STAGESで他のロールに見える可能性がありセキュリティリスクが高くなります。Snowflake公式ドキュメントではStorage Integrationの使用が強く推奨されており、IAMロールベースのアクセス委任によって長期鍵の管理が不要になります。試験でもStorage Integrationが「より安全な選択肢」として問われます。
STORAGE_ALLOWED_LOCATIONSとSTORAGE_BLOCKED_LOCATIONSの関係は?
STORAGE_ALLOWED_LOCATIONSはStorage Integrationがアクセスを許可するクラウドストレージパスの明示的リストです。STORAGE_BLOCKED_LOCATIONSはallowed内であっても特定のサブパスへのアクセスを拒否するための除外リストです。例えばs3://data-bucket/全体を許可しつつ、s3://data-bucket/secrets/は除外するといった設定が可能です。この2つを組み合わせることで、最小権限の原則に基づいた細かなアクセス制御を実現します。
複数のStorage Integrationを使い分けるベストプラクティスは?
環境分離(本番/検証/開発)ごとにStorage Integrationを分けるのが推奨パターンです。各IntegrationのSTORAGE_ALLOWED_LOCATIONSに対応するバケットパスだけを許可し、USAGE ON INTEGRATION権限を環境別のロールに付与します。これにより開発者が誤って本番バケットへアクセスするリスクを排除できます。また、監査の観点でもIntegration単位でACCOUNT_USAGE.ACCESS_HISTORYからアクセスログを分離追跡しやすくなります。
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)を徹底解説。最も簡単...