S3 Tables のカタログ統合を構成して Snowflake Iceberg テーブルを作成するまで
AWS re:Invent 2024 で Apache Iceberg 形式に最適化されたクラウドオブジェクトストアである Amazon S3 Tables が発表されました。現在は東京リージョンでも利用可能になっており、Snowflake でも Iceberg REST カタログ統合 を作成することで、S3 Tables 上の Iceberg テーブルをカタログ統合経由で参照することができます。(Public Preview 機能を含む)
今回、S3 Tables テーブルから Snowflake Iceberg テーブルを作成するまでを実際にやってみたので、備忘も兼ねてその手順についてまとめてみたいと思います。
S3 Tables リソースの準備
テーブルバケット・名前空間の作成
参照元 S3 Tables テーブルが所属するテーブルバケット、および名前空間を作成します。
locals {
table_bucket_name = "sandboxdb-s3tables-iceberg"
namespace = "demo_schema"
}
# S3 Tables Table Bucket
resource "aws_s3tables_table_bucket" "default" {
name = local.table_bucket_name
maintenance_configuration = {
iceberg_unreferenced_file_removal = {
status = "enabled"
settings = { non_current_days = 10, unreferenced_days = 3 }
}
}
}
# S3 Tables Namespace
resource "aws_s3tables_namespace" "default" {
table_bucket_arn = local.namespace
namespace = aws_s3tables_table_bucket.default.arn
}
S3 Tables テーブルの作成
続いて S3 Tables テーブルを作成します。方法はいくつかあると思いますが、今回は以下記事でも紹介しているように Glue ジョブで作成しました。
SparkConf
の設定は S3 Tables 用のものを指定します。
conf = SparkConf()
conf.set("spark.sql.catalog.s3tablesbucket", "org.apache.iceberg.spark.SparkCatalog")
conf.set("spark.sql.catalog.s3tablesbucket.catalog-impl", "software.amazon.s3tables.iceberg.S3TablesCatalog")
conf.set("spark.sql.catalog.s3tablesbucket.warehouse", TABLE_BUCKET_ARN)
conf.set("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions")
クライアント用 IAM ロールの作成
S3 Tables テーブルにアクセスするための、クライアント用 IAM ロールを作成します。
(後述のステップでカタログ統合を作成後、AssumeRole ポリシーを修正します)
locals {
role_name = "sandboxdb-s3tables-client-role"
s3tables_table_bucket = {
name = "sandboxdb-s3tables-iceberg"
}
datalake_administrators_iam_principals = [
"arn:aws:iam::000011112222:role/xxxx",
]
}
# IAM Role
resource "aws_iam_role" "default" {
name = local.role_name
assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
}
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = local.datalake_administrators_iam_principals
}
}
}
resource "aws_iam_role_policy" "default" {
name = "${local.role_name}-policy"
role = aws_iam_role.default.name
policy = data.aws_iam_policy_document.default.json
}
data "aws_iam_policy_document" "default" {
statement {
actions = ["lakeformation:GetDataAccess"]
resources = ["*"]
}
statement {
actions = [
"glue:GetCatalog",
"glue:GetDatabase",
"glue:GetDatabases",
"glue:GetTable",
"glue:GetTables",
"glue:CreateTable",
"glue:UpdateTable",
]
resources = [
"arn:aws:glue:*:${var.account_id}:catalog",
"arn:aws:glue:*:${var.account_id}:catalog/s3tablescatalog",
"arn:aws:glue:*:${var.account_id}:catalog/s3tablescatalog/${local.s3tables_table_bucket.name}",
"arn:aws:glue:*:${var.account_id}:database/s3tablescatalog/${local.s3tables_table_bucket.name}/*",
"arn:aws:glue:*:${var.account_id}:table/s3tablescatalog/${local.s3tables_table_bucket.name}/*/*",
]
}
}
カタログ統合の構成
Iceberg REST のカタログ統合を作成します。[1]
執筆時点最新の Terraform Provider Version v2.1.0 にはカタログ統合の Resource がなさそうなので、SQL で作成することにします。
USE ROLE accountadmin;
CREATE OR REPLACE CATALOG INTEGRATION catalog_int_rest__iceberg_sandboxdb
CATALOG_SOURCE = ICEBERG_REST
TABLE_FORMAT = ICEBERG
CATALOG_NAMESPACE = 'default'
REST_CONFIG = (
CATALOG_URI = 'https://glue.ap-northeast-1.amazonaws.com/iceberg'
CATALOG_API_TYPE = AWS_GLUE
WAREHOUSE = '000011112222:s3tablescatalog/sandboxdb-s3tables-iceberg'
ACCESS_DELEGATION_MODE = vended_credentials
)
REST_AUTHENTICATION = (
TYPE = SIGV4
SIGV4_IAM_ROLE = 'arn:aws:iam::000011112222:role/sandboxdb-s3tables-client-role'
SIGV4_SIGNING_REGION = 'ap-northeast-1'
)
ENABLED = TRUE
;
Snowflake 環境 IAM ユーザー ARN と外部 ID を確認します。
DESC CATALOG INTEGRATION catalog_int_rest__iceberg_sandboxdb;
Snowflake 環境 IAM ユーザーから AssumeRole できるよう、クライアント用 IAM ロールの AssumeRole Policy を修正します。
locals {
external_identifiers = {
iam_user_arn = "arn:aws:iam::777788889999:user/username"
external_id = "XY12345_SFCRole=xxxxxxxx"
}
}
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = local.datalake_administrators_iam_principals
}
}
# Add Statement
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = [ local.external_identifiers.iam_user_arn ]
}
condition {
test = "StringEquals"
variable = "sts:ExternalId"
values = [ local.external_identifiers.external_id ]
}
}
}
正常に構成できていれば、SYSTEM$VERIFY_CATALOG_INTEGRATION のレスポンスに含まれる "success"
の値が true
になります。
SELECT SYSTEM$VERIFY_CATALOG_INTEGRATION('CATALOG_INT_REST__ICEBERG_SANDBOXDB');
-- {"success" : true, "errorCode" : "", "errorMessage" : ""}
Lake Formation の設定
クライアント用 IAM ロールに対して、必要な Lake Formation 権限を Grant します。
Resource Type | Resources | Permissions |
---|---|---|
Catalog | 000011112222:s3tablescatalog/sandboxdb-s3tables-iceberg |
Describe |
Database | 000011112222:s3tablescatalog/sandboxdb-s3tables-iceberg/demo_schema |
Describe |
Table | 000011112222:s3tablescatalog/sandboxdb-s3tables-iceberg/demo_schema/* |
* |
Snowflake のような外部エンジンから S3 Tables を利用するにあたり、以下の Lake Formation 設定にチェックを入れます。
-
[ Administration ]
>[ Application integration settings ]
>Allow external engines to access data in Amazon S3 locations with full table access
Snowflake Iceberg テーブルの作成
カタログ統合を使用して、Snowflake Iceberg テーブルを作成します。
CREATE OR REPLACE ICEBERG TABLE sandboxdb.demo_schema.users
CATALOG = 'CATALOG_INT_REST__ICEBERG_SANDBOXDB'
CATALOG_NAMESPACE = 'demo_schema'
CATALOG_TABLE_NAME = 'users'
AUTO_REFRESH = TRUE
;
データを参照できることを確認できます。
SELECT * FROM sandboxdb.demo_schema.users LIMIT 100;
参考
- Snowflake integrates with Amazon S3 Tables - by @jeeminsim, Medium
- Connect Snowflake to S3 Tables using the SageMaker Lakehouse Iceberg REST endpoint - AWS Blog
-
CREATE CATALOG INTEGRATION (Apache Iceberg™ REST) - Snowflake Documentation ↩︎

Snowlfake データクラウドのユーザ会 SnowVillage のメンバーで運営しています。 Publication参加方法はこちらをご参照ください。 zenn.dev/dataheroes/articles/db5da0959b4bdd
Discussion