SnowflakeはS3, Blob, GCSを外部ステージとして設定し、データをロードする機能を備えています。
Snowflakeは各クラウドストレージとの接続方法として「ストレージ統合」の使用を推奨しています。
今回、GCSとのストレージ統合を設定し、外部ステージのロード先としてみました。
その手順等を感想を混ぜつつ書いてみようと思います。
参考にしたSnowflake公式ドキュメントは以下です。
ストレージ統合の設定方法がステップbyステップで示されています。
Google Cloud Storageの統合の構成
この記事は、公式が説明するステップに従って書いていきます。
【目次】
- ∨GCSとストレージ統合
- ∨Snowflakeでストレージ統合を作成する
- ∨自動生成されたサービスアカウントの情報を取得
- ∨バケットオブジェクトにアクセスするためのサービスアカウント権限を付与する
- ∨外部ステージの作成
- ∨まとめ
GCSとストレージ統合
一般に、各ストレージサービスと連携する際、接続に必要な接続情報が必要です。
接続情報を自力で保管し使用する場合、セキュリティリスクに晒されるため、
Snowflakeはよりセキュアな方法として「ストレージ統合」機能を提供しています。
現在、Snowflakeは「ストレージ統合」機能のみを推奨しています。
各クラウドプロバイダ毎に実装方法は異なり、GCSの場合、Service Accountを使用します。
クラウドプロバイダ間で概念が異なるため 「AWSでいうところのXXXだよね」 は誤解を生みますが、
簡単に言えば、AWSのIAM、Azureのサービスプリンシパル、が相当すると思います。(本当??)
以下の図はその概念図です。(公式直リンク)
Snowflakeは、ストレージ統合オブジェクトをGCS用のサービスアカウントと紐付けます。
このサービスアカウントは裏でSnowflakeが作成します。
言い換えると、GCSの認証責任をSnowflakeが作成するサービスアカウントに委任します。
Snowflake上のロード・アンロード操作の裏で透過的にサービスアカウントの権限参照が行われます。
Snowflakeでストレージ統合を作成する
Snowflake上でストレージ統合を作る方法は以下の通りです。
実行にはACCOUNTADMINロールか、CREATE INTEGRATION権限が必要です。
ストレージ統合を作成する段階では、GCP側の権限設定は不要です。
1 2 3 4 5 6 |
CREATE STORAGE INTEGRATION gcs_int TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'GCS' ENABLED = TRUE STORAGE_ALLOWED_LOCATIONS = ('gcs://mybucket1/path1/', 'gcs://mybucket2/path2/') STORAGE_BLOCKED_LOCATIONS = ('gcs://mybucket1/path1/sensitivedata/', 'gcs://mybucket2/path2/sensitivedata/'); |
自動生成されたサービスアカウントの情報を取得
CREATE INTEGRATIONによって作られたSnowflake用のサービスアカウント情報を取得します。
オブジェクトの詳細情報を取得する DESC コマンドにより取得できます。
1 2 3 4 5 6 7 8 9 10 |
DESC STORAGE INTEGRATION gcs_int; +-----------------------------+---------------+-----------------------------------------------------------------------------+------------------+ | property | property_type | property_value | property_default | +-----------------------------+---------------+-----------------------------------------------------------------------------+------------------| | ENABLED | Boolean | true | false | | STORAGE_ALLOWED_LOCATIONS | List | gcs://mybucket1/path1/,gcs://mybucket2/path2/ | [] | | STORAGE_BLOCKED_LOCATIONS | List | gcs://mybucket1/path1/sensitivedata/,gcs://mybucket2/path2/sensitivedata/ | [] | | STORAGE_GCP_SERVICE_ACCOUNT | String | service-account-id@project1-123456.iam.gserviceaccount.com | | +-----------------------------+---------------+-----------------------------------------------------------------------------+------------------+ |
STORAGE_GCP_SERVICE_ACCOUNTプロパティが、作成されたサービスアカウントです。
バケットオブジェクトにアクセスするためのサービスアカウント権限を付与する
最後に、サービスアカウントがバケットへアクセスするための権限設定を行います。
ここで初めて、GCPコンソール上での操作が必要となります。
カスタムIAMロールの作成
以下の権限を持つIAMロールを作成します。今回はロードのみを行うため以下を設定します。
パージを行う場合はobjects.delte、アンロードを行う場合はobjects.createが必要です。
- storage.buckets.get
- storage.objects.delete
- storage.objects.get
- storage.objects.list
サービスアカウントへIAMロールを割り当てる
GCPのやり方に従って、サービスアカウントへIAMロールを割り当てます。
バケットに対して、サービスアカウントのアクセスを許可し、その許可内容をIAMロールで指定します。
Azureと比較するとAWSとGCPは近いなと感じます。
外部ステージの作成
まず、ステージオブジェクトを格納するSnowflakeデータベースへの権限付与を行います。
1 2 3 4 |
GRANT USAGE ON DATABASE mydb TO ROLE myrole; GRANT USAGE ON SCHEMA mydb.stages TO ROLE myrole; GRANT CREATE STAGE ON SCHEMA mydb.stages TO ROLE myrole; GRANT USAGE ON INTEGRATION gcs_int TO ROLE myrole; |
次にストレージ統合を指定して外部ステージオブジェクトを作成します。
1 2 3 4 5 6 |
USE SCHEMA mydb.stages; CREATE STAGE my_gcs_stage URL = 'gcs://mybucket1' STORAGE_INTEGRATION = gcs_int FILE_FORMAT = my_csv_format; |
最後に疎通試験を行います。
1 |
copy into testtable from @my_gcs_stage pattern='testdata.csv'; |
まとめ
Snowflakeの公式ドキュメントの通りにGCSとのストレージ統合を作成しました。
また、作成したストレージ統合上に外部ステージを設定し、ロードが出来ることを確認しました。