SnowflakeのS3とのストレージ統合をCloudFormationでさくっと設定する
データアナリティクス事業本部、池田です。
別のブログ作業で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 の考慮はしていません。 必要に応じて冒頭で紹介した記事など参考に適宜テンプレート変更して使っていただけたらと思います。