【技術ブログ】SnowflakeとS3の連携:ストレージ統合の設定手順
こんにちは。Turtleです。
今回は、SnowflakeとAmazon S3を連携させるための設定手順について解説します。
1. はじめに
SnowflakeでAmazon S3のデータを安全に取得するには、「Storage Integration (ストレージ統合)」を使用するのがベストプラクティスとされます。
以下では、AWS IAMロールとSnowflakeの認証を連携して、S3にセキュアにアクセスする方法を解説します。
2. 実装(AWSの設定)
以下、AWS側で実施する必要がある設定を解説します。
S3バケット、IAMポリシー、IAMロールを1から作成する前提で記載していますので、必要に応じて読み飛ばしていただいて構いません。
2-1. S3の作成
まず、以下手順でSnowflakeからアクセスするS3バケットを作成します。
AWSマネジメントコンソールにログインし、「S3」に移動する
「バケットを作成」をクリックし、バケット作成画面に移動する
バケットタイプを「汎用」に設定し、任意のバケット名を入力
オブジェクト所有者を「ACL有効」「希望するバケット所有者」に設定
「パブリックアクセスをすべてブロック」にチェック
その他の設定を確認し、「バケットを作成」をクリック
(※任意で必要な箇所の設定変更をお願いします)
2-2. IAMポリシーの作成
次に、以下手順でSnowflakeがS3にアクセスするためのIAMポリシーを作成します。
IAMコンソールで「ポリシー」を選択
「ポリシーの作成」をクリック
JSONタブを選択し、以下のポリシーを入力:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:ListBucket",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::<bucket>",
"arn:aws:s3:::<bucket>/*"
]
}
]
}
# 以下、必要に応じて最小権限を付与するようにする
# `s3:GetBucketLocation`: バケットのリージョンを取得
# `s3:GetObject`: オブジェクトの読み取り
# `s3:GetObjectVersion`: オブジェクトのバージョン取得
# `s3:ListBucket`: バケットの内容一覧取得
# `s3:PutObject`: オブジェクトの書き込み
# `s3:DeleteObject`: オブジェクトの削除4. ポリシー名を入力し、「ポリシーを作成」をクリック
2-3. IAMロールの作成
次に、以下手順で作成したポリシーを適用するIAMロールを作成します。
IAMコンソールで「ロール」を選択
「ロールを作成」をクリック
「信頼されたエンティティタイプ」で「カスタム信頼ポリシー」を選択
エディタ部分に以下を入力:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<アカウントID>:root"
},
"Action": "sts:AssumeRole"
}
]
}
# `<アカウントID>`: 自身のアカウントIDを入力(コンソール画面右上で確認可)5. 「2-2. IAMポリシーの作成」で作成したポリシーをアタッチ
6. ロール名を入力し、「ロールの作成」をクリック
2-4. S3バケットポリシーの設定
次に、以下手順でS3バケットにアクセス権限を設定します。
S3バケットの「アクセス許可」タブを開く
「バケットポリシー」セクションで「編集」をクリック
以下のポリシーを追加:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<アカウントID>:role/<ロール名>"
},
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:ListBucket",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::<バケット名>",
"arn:aws:s3:::<バケット名>/*"
]
}
]
}
# `<アカウントID>`: 自身のアカウントIDを入力(コンソール画面右上で確認可)
# `<ロール名>`: 2-3で作成したロール名を入力
# `<バケット名>`: 2-1で作成したバケット名を入力 2-5. IAMロールの信頼ポリシーの編集
最後に、以下手順でIAMロールの信頼ポリシーを更新します。
作成したIAMロールを選択
「信頼関係」タブを開く
「信頼ポリシーの編集」をクリック
以下のポリシーを入力:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "<SnowflakeのIAMユーザーARN>"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<Snowflakeの外部ID>"
}
}
}
]
}
# `<SnowflakeのIAMユーザーARN>`: 3-1で取得する値を入力(Snowflakeで取得する)
# `<Snowflakeの外部ID>`: 3-1で取得する値を入力(Snowflakeで取得する)3. 実装(Snowflakeの設定)
以下、Snowflakeで実施する必要がある設定を解説します。
ACCOUNTADMINを使用する前提で記載していますので、必要に応じて使用するロールは変更してください。
3-1. ストレージ統合の作成
AWS側の設定が完了したら、Snowflakeでストレージ統合を作成します。
以下のSQLを実行することで、ストレージ統合の作成が可能です。
use role accountadmin;
create storage integration <integration_name>
type = EXTERNAL_STAGE
storage_provider = 'S3'
enabled = TRUE
storage_aws_role_arn = '<IAMロールのARN>'
storage_allowed_locations = ('s3://<bucket>/<prefix>/');
# `<integration_name>`: ストレージ統合の名前
# `<IAMロールのARN>`: AWSで作成したIAMロールのARN
# `<bucket>`: S3バケット名
# `<prefix>`: アクセスを許可するパス無事作成が完了したら、ストレージ統合の情報を以下クエリで出力します。
desc integration <integration_name>;以下の情報は「2-5. IAMロールの信頼ポリシーの編集」で使用しますので、控えておいてください。
STORAGE_AWS_IAM_USER_ARN
STORAGE_AWS_EXTERNAL_ID
3-2. 外部ステージの作成
ストレージ統合を使用して外部ステージを作成します。
use role accountadmin;
create stage <stage_name>
storage_integration = <integration_name>
url = 's3://<bucket>/<prefix>/'
file_format = (type = 'CSV');
# `<stage_name>`: ステージの名前
# `<integration_name>`: 作成したストレージ統合の名前
# `<bucket>`: S3バケット名
# `<prefix>`: アクセスするパス3-3. 動作確認
設定が完了したら、実際に動作確認を行います。
以下を実行し、リストが表示されたら正しく設定が行えています。
list @<stage_name>;4. おわりに
以上で、SnowflakeからIAMロールを使用してセキュアにS3にアクセスすることが可能になりました。
AWSとSnowflakeの設定が必要で、やや手順が多く見えるかもしれませんが、然るべきステップを踏んで進めていけばそこまで手間ではありません。
本記事が少しでも誰かのお役に立つことができれば嬉しく思います。
それでは!
