この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部、池田です。
別のブログ作業でSnowflakeと
Amazon S3 を接続する必要があり、
推奨される ストレージ統合(Storage Integration)
で行いました。その作業を AWS CloudFormation
でできるようにテンプレートを作成したので、簡単に紹介します。
↓以下の記事を参考にしてテンプレートを作成しました。
【 Amazon S3からSnowflakeへのバルクロードを設定からやってみた 】
【 Simplifying Snowflake access to S3 】
Snowflake側作業
先にストレージ統合をSQLで作ってしまいます。
ACCOUNTADMIN
ロールなどで作業する必要があります。
USE ROLE ACCOUNTADMIN;
CREATE STORAGE INTEGRATION {ストレージ統合名}
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = S3
ENABLED = TRUE
STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::{S3のAWSアカウントID}:role/{作成予定のロール名}'
STORAGE_ALLOWED_LOCATIONS = ('s3://{S3のバケット名}/{パス}/');
DESC INTEGRATION {ストレージ統合名};
(次章では、作成予定のロール名のデフォルトを snowflake-s3-access-role
としています。)
成功すると↑の最終行のDESCの結果として、
↓以下のような情報が得られます。
property property_type property_value property_default
ENABLED Boolean true false
STORAGE_PROVIDER String S3
STORAGE_ALLOWED_LOCATIONS List s3://{S3のバケット名}/{パス}/ []
STORAGE_BLOCKED_LOCATIONS List []
STORAGE_AWS_IAM_USER_ARN String {SnowflakeのIAMユーザー(CloudFormationで使う)}
STORAGE_AWS_ROLE_ARN String arn:aws:iam::{S3のAWSアカウントID}:role/{作成予定のロール名}
STORAGE_AWS_EXTERNAL_ID String {外部ID(CloudFormationで使う)}
STORAGE_AWS_IAM_USER_ARN
と STORAGE_AWS_EXTERNAL_ID
が次章で必要になります。
AWS側作業
以下ようなCloudFormationテンプレートを作成しました。 これを使ってCloudFormationのコンソールや CLI などからリソースの作成ができます。
AWSTemplateFormatVersion: "2010-09-09"
Description: "Create a role for Snowflake."
Parameters:
RoleName:
Type: "String"
Default: "snowflake-s3-access-role"
BucketName:
Type: "String"
BucketPrefix:
Type: "String"
StorageAwsIamUserArn:
Type: "String"
Description: "DESC INTEGRATION {integration_name};"
StorageAwsExternalId:
Type: "String"
Description: "DESC INTEGRATION {integration_name};"
Resources:
SnowflakeS3AccessRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Ref RoleName
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !Ref StorageAwsIamUserArn
Action: sts:AssumeRole
Condition:
StringLike:
sts:ExternalId: !Ref StorageAwsExternalId
Policies:
- PolicyName: !Sub "${RoleName}-policy"
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
# - s3:PutObject
# - s3:DeleteObject
Resource: !Sub "arn:aws:s3:::${BucketName}/${BucketPrefix}/*"
- Effect: Allow
Action:
- s3:ListBucket
Resource: !Sub "arn:aws:s3:::${BucketName}"
Condition:
StringLike:
s3:prefix: !Sub "${BucketPrefix}/*"
(ポリシーはロードのための参照系に絞っています。)
コンソールで作成した場合のパラメータは↓こんな感じ。
(作成予定のロール名→ snowflake-s3-access-role
、S3のパス(ディレクトリ)→ snowflake
としています。)
動作確認
↓こんな感じで簡単な外部ステージを作成して、ファイルが参照できるか確認しました。
USE ROLE ACCOUNTADMIN;
CREATE STAGE CHECK_EXT_STAGE_S3
STORAGE_INTEGRATION = {ストレージ統合名}
URL = 's3://{S3のバケット名}/{パス}/';
list @CHECK_EXT_STAGE_S3;
実際はこのあと、 GRANT USAGE ON INTEGRATION {ストレージ統合名} TO ROLE {実際に使用するロール};
で、ACCOUNTADMIN以外でも作成したストレージ統合を使用できるように権限を振って、
きちんとしたステージを作成しました。
おわりに
今回は簡単な紹介のため、 接続するS3のパスが複数の場合や、 KMS の考慮はしていません。 必要に応じて冒頭で紹介した記事など参考に適宜テンプレート変更して使っていただけたらと思います。