Snowflakeのストレージ統合でAWS S3と連携する手順を図解してみる
はじめに
こんにちは、ほっそーです。
「Snowflakeと外部のAWSアカウント間でデータ連携して、S3のデータをロードしたい」
そう思って調べてみると、Storage Integration や IAMロールなど、いくつか設定が必要になります。
ただ、Snowflake側とAWS側それぞれで何を設定すればいいのか、最初は少し分かりづらく感じました。
この記事では、自分が実際に試しながら整理した手順を、図を交えてまとめていきます。
参考
本記事は、以下の公式ドキュメントを参考に検証しています。
Snowflake公式ドキュメント(S3とのストレージ統合設定)
本記事で紹介すること
- Snowflakeと外部AWSアカウント間のストレージ統合の仕組み
- データ連携の設定手順
本記事で紹介しないこと
- Snowflakeの基本的な説明
- AWSのIAMロールの仕組み
やりたいこと

外部のAWSアカウントにあるS3バケットのCSVファイルデータを、Snowflakeから参照・ロードできるようにしたいです。
そのために、Snowflake側でストレージ統合(Storage Integration)と 外部ステージ(External Stage) を設定し、S3上のファイルをSnowflakeから扱える状態を目指します。
最終イメージ
最終的な構成は以下のようになります。

Snowflakeから外部ステージを経由して、外部AWSアカウントのS3バケットにアクセスする構成です。このとき、Storage Integrationを通じてIAMロールをAssumeすることで、S3へのアクセス権限を取得します。
※データは同期されるのではなく、必要に応じてS3を参照します。
以降、手順を図解しながら説明していきます。
設定手順
Step1: S3バケットを操作可能なIAMロールを用意する (外部AWS アカウント側)

まず、外部AWSアカウント側で、S3バケットにアクセスするためのIAMロールを作成します。
このロールは、後続の手順でSnowflakeからAssume Roleされるため、S3へアクセスするための権限を持たせておく必要があります。
Step2: 外部ストーレージ統合を作成する (Snowflake側)

次に、Snowflake側でストレージ統合(Storage Integration)を作成します。
ストレージ統合とは、外部AWSアカウントのリソース(S3など)にアクセスするための設定です。
CREATE STORAGE INTEGRATION '<任意のストレージ統合名>'
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'S3'
ENABLED = TRUE
STORAGE_AWS_ROLE_ARN = '<Step1で作成したIAMロールのARN>'
STORAGE_ALLOWED_LOCATIONS = ('<参照対象となるS3バケットURI>')※ STORAGE_ALLOWED_LOCATIONS に指定したS3パス以外にはアクセスできない点に注意してください。
この設定により、Snowflakeから外部AWSアカウントのIAMロールを利用して、S3バケットへアクセスできるようになります。
作成後は、以下のコマンドで設定内容を確認します。
DESC INTEGRATION '<作成したストレージ統合名>';実行結果には、後続の設定で使用するIAMユーザーやExternal IDが含まれるため、控えておきます。
| property | property_value |
|--------------------------|----------------|
| STORAGE_AWS_IAM_USER_ARN | arn:aws:iam::xxxx:user/xxx |
| STORAGE_AWS_EXTERNAL_ID | xxxxxxxxxxxxxxxx |Step3: SnowflakeからのAssume Roleを許可する/IAMロールの信頼ポリシー設定 (外部AWS アカウント側)

次に、外部AWSアカウント側でIAMロールの信頼ポリシーを設定します。
Step2で払い出されたIAMユーザー(STORAGE_AWS_IAM_USER_ARN)とExternal ID(STORAGE_AWS_EXTERNAL_ID)を信頼ポリシーに設定することで、Snowflake側から外部アカウントのIAMロールをAssumeできるようになります。
信頼ポリシーの例は以下の通りです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "<Step2で確認したIAMユーザーのARN(STORAGE_AWS_IAM_USER_ARN)>"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<Step2で確認した外部ID(STORAGE_AWS_EXTERNAL_ID)>"
}
}
}
]
}※External IDを指定することで、意図しない第三者からのAssume Roleを防ぐことができます。
Step4: ストレージ統合と紐づいた外部ステージを作成する (Snowflake側)

最後に、Snowflake側で外部ステージを作成します。
外部ステージとは、S3などの外部ストレージ上のデータを参照するための定義です。
実行クエリは以下の通りです。
CREATE STAGE <ステージ名>
STORAGE_INTEGRATION = <Step2で作成したストレージ統合名>
URL = '<S3バケットのパス>'
FILE_FORMAT = <事前に作成したファイルフォーマット>;外部ステージは、対象のデータベース/スキーマ内に作成します。
今回はCSVファイルを扱うため、事前にファイルフォーマットも作成しておきます。
CREATE FILE FORMAT <フォーマット名>
TYPE = 'CSV'
FIELD_DELIMITER = ','
SKIP_HEADER = 1;動作確認してみる

ここまでの設定が正しく行えていれば、SnowflakeからS3上のデータを参照・ロードできるようになっているはずです。
まずは、作成した外部ステージの内容を確認してみます。
LIST @<ステージ名>;S3上のファイル一覧が表示されれば、外部ステージの設定は正しく行われています。
続いて、実際にデータをロードしてみます。
COPY INTO <テーブル名>
FROM @<ステージ名>
FILE_FORMAT = (FORMAT_NAME = <フォーマット名>);エラーが発生せず、データが正常にロードできれば成功です。
最後に、ロードされたデータを確認します。
SELECT * FROM <テーブル名>;また、SnowflakeからS3へのデータのアンロード(ダウンロード)も可能です。
COPY INTO @<ステージ名>/<ファイル名>
FROM <テーブル名>
FILE_FORMAT = (FORMAT_NAME = <フォーマット名>);このように、外部ステージを利用することで、S3との間で双方向にデータをやり取りすることができます。
注意点
- ストレージ統合を利用するには、対象のストレージ統合に対するUSAGE権限を持つロールで操作する必要があります。
GRANT USAGE ON INTEGRATION <ストレージ統合名> TO ROLE <ロール名>;- 複数のAWSアカウントと連携する場合は、それぞれに対応するストレージ統合を作成する必要があります。
最後に
以上です。
Snowflake側と外部AWSアカウント側の両方で設定が必要なため、最初は少し難しく感じるかもしれませんが、一度流れを掴めば問題なく設定できると思います。
本記事が参考になれば幸いです。
