AWS

Snowflakeのストレージ統合でAWS S3と連携する手順を図解してみる

hosso

はじめに

こんにちは、ほっそーです。
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アカウント側の両方で設定が必要なため、最初は少し難しく感じるかもしれませんが、一度流れを掴めば問題なく設定できると思います。
本記事が参考になれば幸いです。

AUTHOR
hosso
hosso
記事URLをコピーしました