VOOZH about

URL: https://zenn.dev/penginpenguin/articles/97f30cc1ac8377

⇱ AWSのレイクハウス(Apache Iceberg)をSnowflakeと連携する2つのパターンを整理する


AWS
Snowflake
dataengineering
tech

はじめに

AWS Community Builderのぺんぎん(@jitepengin)です。
近年、Apache Icebergを中心としたレイクハウスを構築することが増えてきています。

レイクハウスアーキテクチャ以前は

  • AWSならAmazon Redshiftを中心とした構成
  • Snowflakeなら内部テーブルを中心とした構成

のように、特定のプラットフォームにデータを集約する設計が一般的でした。
しかし、Apache Icebergの登場によりこの前提は大きく変わりつつあります。

S3上のデータを複数のエンジンから直接扱えるようになったことで、重要なのは単なる製品選定ではなく、
どこにデータを持ち、誰が書き込み責任やガバナンス主権をもつのかというアーキテクチャ設計そのものになりました。

本記事では、AWSとSnowflakeの共存をテーマに、

  • S3 × Icebergを前提とした2つのパターン
  • Power BI Serviceとの接続
  • AI活用まで含めた今後の展望

を整理します。

なぜAWS × Snowflakeの共存が必要なのか

Apache Icebergの最大の価値は、データとクエリエンジンを分離できることにあります。
たとえばデータ実体をS3に保持したまま、Athena、AWS Glue / Spark、Redshift、Snowflakeなど複数のツールから同じデータを扱うことができます。
つまり、データの実体は一箇所に集約しつつ、用途に応じて最適な分析基盤を選択できるようになりました。

これによる、アーキテクチャの論点は、「どの製品を使うか」から「どこにデータ主権を置き、どこに分析主導権を持たせるか」に変わってきたと言えます。

ここでSnowflakeを利用するメリットは、

  • ユーザフレンドリーなUI/UX
  • 強力なSQL分析機能
  • Cortex AIとの統合

にあります。
特に、AWSをデータの主権レイヤとしつつ、Snowflakeを分析レイヤとして活用する構成は非常に相性が良いと考えています。

Snowflake × S3 の2つのパターン

SnowflakeとS3を連携する場合によく使われる2つのパターンを整理します。

パターン1:Glue Catalog Integration

👁 Image

S3上のIcebergテーブルを、AWS Glue Data Catalogを介してSnowflakeから参照します。

この構成のメリットは

  • 比較的シンプルに構成できる
  • S3がSingle Source of Truthとなる
  • Snowflakeからの書き込みができないため、データ管理の主権がAWSになる(こちらはデメリットでもあります。)
  • ユーザからのアクセスはSnowflakeに集約されるため、権限コントロールをSnowflakeに寄せることができる

つまり、Snowflakeはデータ分析(クエリエンジン)としての役割に徹し、AWSがデータ管理の権限を持つ構成です。

設定方法

Step 1: External Volumeを作成(S3へのアクセス設定)

Snowflake側で下記を実行

CREATE EXTERNAL VOLUME IF NOT EXISTS sample_iceberg_volume
 STORAGE_LOCATIONS = (
 (
 NAME = 'my-s3-location'
 STORAGE_PROVIDER = 'S3'
 STORAGE_BASE_URL = カタログS3パス
 STORAGE_AWS_ROLE_ARN = 使用するロール名
 STORAGE_AWS_EXTERNAL_ID = 'my_external_id'
 )
 );
Step 2: Glueカタログ統合を作成

Snowflake側で下記を実行

CREATE OR REPLACE CATALOG INTEGRATION glue_catalog_int →任意の名称
 CATALOG_SOURCE = GLUE
 CATALOG_NAMESPACE = Glueカタログのネームスペース
 TABLE_FORMAT = ICEBERG
 GLUE_AWS_ROLE_ARN = 使用するロール名
 GLUE_CATALOG_ID = 使用するGlueカタログのID
 GLUE_REGION = 'ap-northeast-1'
 ENABLED = TRUE;
Step 3: AWS 信頼ポリシーに必要な情報を取得
DESC EXTERNAL VOLUME sample_iceberg_volume;

→ STORAGE_AWS_IAM_USER_ARNとSTORAGE_AWS_EXTERNAL_IDをメモ

DESC CATALOG INTEGRATION glue_catalog_int;

→ GLUE_AWS_IAM_USER_ARNとGLUE_AWS_EXTERNAL_IDをメモ

AWS側で使用するロールに信頼ポリシーを設定してください。

{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Principal": {
 "AWS": STORAGE_AWS_IAM_USER_ARN
 },
 "Action": "sts:AssumeRole",
 "Condition": {
 "StringEquals": {
 "sts:ExternalId": STORAGE_AWS_EXTERNAL_ID
 }
 }
 },
 {
 "Effect": "Allow",
 "Principal": {
 "AWS": GLUE_AWS_IAM_USER_ARN
 },
 "Action": "sts:AssumeRole",
 "Condition": {
 "StringEquals": {
 "sts:ExternalId": GLUE_AWS_EXTERNAL_ID
 }
 }
 }
 ]
}
Step 4: DBを作成

Snowflake側で下記を実行

CREATE DATABASE IF NOT EXISTS icebergdb;
Step 5: テーブル作成

Snowflake側で下記を実行

CREATE OR REPLACE ICEBERG TABLE icebergdb.public.yellow_tripdata →任意の名称
 EXTERNAL_VOLUME = 'sample_iceberg_volume' →Step 1で作成したEXTERNAL_VOLUME名
 CATALOG = 'glue_catalog_int' →Step 2で作成したカタログ名
 CATALOG_TABLE_NAME = 'yellow_tripdata' →Glueカタログ上のテーブル名
 AUTO_REFRESH = TRUE;
Step 6: データ確認

Snowflake側で下記を実行

SELECT * FROM icebergdb.public.yellow_tripdata LIMIT 5;

👁 Image

S3のデータを読み込むことができました!

パターン2:Catalog-Linked Database(Iceberg)

👁 Image

こちらはGlue CatalogをREST Catalogで連携し、Snowflake側でIcebergテーブルを統合する方式です。

この構成のメリットは

  • Snowflakeから読み書きが可能
  • データ実体はS3に保持したまま運用できる
  • SnowflakeユーザがSQLベースで更新・分析を実施できる
  • Power BIやCortex AIとの連携がしやすい

つまり、データ実体をS3に保持したままSnowflakeから分析・更新できるということが大きな特徴です。
ただし、AWS側でのガバナンスとSnowflake側でのガバナンスの双方で考える必要があります。

設定方法

Step 1: External Volumeを作成(S3へのアクセス設定)

Snowflake側で下記を実行

CREATE EXTERNAL VOLUME IF NOT EXISTS sample_iceberg_volume
 STORAGE_LOCATIONS = (
 (
 NAME = 'my-s3-location'
 STORAGE_PROVIDER = 'S3'
 STORAGE_BASE_URL = カタログS3パス
 STORAGE_AWS_ROLE_ARN = 使用するロール名
 STORAGE_AWS_EXTERNAL_ID = 'my_external_id'
 )
 );
Step 2: Glue Iceberg RESTカタログ統合を作成

Snowflake側で下記を実行

CREATE OR REPLACE CATALOG INTEGRATION glue_rest_catalog_int
 CATALOG_SOURCE = ICEBERG_REST
 TABLE_FORMAT = ICEBERG
 CATALOG_NAMESPACE = Glueカタログのネームスペース
 REST_CONFIG = (
 CATALOG_URI = GlueカタログのURI
 CATALOG_API_TYPE = AWS_GLUE
 CATALOG_NAME = AWSアカウントID
 )
 REST_AUTHENTICATION = (
 TYPE = SIGV4
 SIGV4_IAM_ROLE = 使用するロール名
 SIGV4_SIGNING_REGION = 'ap-northeast-1'
 )
 ENABLED = TRUE;
Step 3: AWS 信頼ポリシーに必要な情報を取得
DESC EXTERNAL VOLUME sample_iceberg_volume;

→ STORAGE_AWS_IAM_USER_ARNとSTORAGE_AWS_EXTERNAL_IDをメモ

DESC CATALOG INTEGRATION glue_rest_catalog_int;

→ GLUE_AWS_IAM_USER_ARNとGLUE_AWS_EXTERNAL_IDをメモ

AWS側で使用するロールに信頼ポリシーを設定してください。

{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Principal": {
 "AWS": STORAGE_AWS_IAM_USER_ARN
 },
 "Action": "sts:AssumeRole",
 "Condition": {
 "StringEquals": {
 "sts:ExternalId": STORAGE_AWS_EXTERNAL_ID
 }
 }
 },
 {
 "Effect": "Allow",
 "Principal": {
 "AWS": GLUE_AWS_IAM_USER_ARN
 },
 "Action": "sts:AssumeRole",
 "Condition": {
 "StringEquals": {
 "sts:ExternalId": GLUE_AWS_EXTERNAL_ID
 }
 }
 }
 ]
}
Step 4: Catalog Linked Database を作成(読み書き可)

Snowflake側で下記を実行

CREATE DATABASE my_iceberg_linked_db
 LINKED_CATALOG = (
 CATALOG = 'glue_rest_catalog_int', →Step 2で作成したカタログ名
 ALLOWED_WRITE_OPERATIONS = ALL
 )
 EXTERNAL_VOLUME = 'sample_iceberg_volume';
Step 5: テーブルが自動検出される(30秒ごと同期)

Snowflake側で下記を実行

SELECT * FROM my_iceberg_linked_db."icebergdb"."yellow_tripdata" LIMIT 5;

👁 Image

S3のデータを読み込むことができました!

Step 6: 書き込みテスト

Snowflake側で下記を実行

INSERT INTO my_iceberg_linked_db."icebergdb"."yellow_tripdata"
 (vendorid, tpep_pickup_datetime, tpep_dropoff_datetime, passenger_count,
 trip_distance, ratecodeid, store_and_fwd_flag, pulocationid, dolocationid,
 payment_type, fare_amount, extra, mta_tax, tip_amount, tolls_amount,
 improvement_surcharge, total_amount, congestion_surcharge, airport_fee)
VALUES
 (1, '2025-01-01 13:00:00', '2025-01-01 13:30:00', 2,
 3.5, 1, 'N', 100, 200,
 1, 15.0, 2.5, 0.5, 3.0, 0,
 1.0, 22.0, 2.5, 0);
Step 7: 書き込み確認

Snowflake側で下記を実行

SELECT * FROM my_iceberg_linked_db."icebergdb"."yellow_tripdata"
WHERE tpep_pickup_datetime = '2025-01-01 13:00:00';

👁 Image

S3に書き込むことができました!

Athena側

書き込み前
👁 Image

書き込み後
👁 Image

どのパターンを選ぶべきか

実務では以下のように整理すると分かりやすいです。

ケース 推奨パターン
AWS側ETLが主、Snowflakeは参照中心 パターン 1
BI / AI / SQL更新をSnowflake主導で実施 パターン 2
ガバナンスをAWSに集約したい パターン 1
Snowflakeユーザー主体の運用 パターン 2

Power BI Serviceとの接続

従来、S3で構成したレイクハウスをPower BI Serviceで参照する場合、Redshiftを介して接続する場面が多かったと思います。
その際、Power BI Serviceからセキュアに直接接続しようとすると、EC2を建ててオンプレミスデータゲートウェイを構成する必要がありました。
この場合、EC2の管理コストなどが発生してしまいます。

👁 Image

さて、Snowflakeではどうでしょうか。

👁 Image

Power BIにはSnowflake向けのネイティブコネクタが用意されており、Power BI Serviceから直接認証・接続できるため、Redshift構成で必要になりがちな中継サーバやオンプレミスデータゲートウェイを省略できます。
つまり、オンプレミスデータゲートウェイといった運用コストのかかる構成を除外することが可能となります。
また、Snowflake側でセマンティックに整理したGold層をそのままPower BIへ接続できるため、BI利用者の利便性向上にもつながります。

メダリオンアーキテクチャで考える

個人的には以下の構成が非常に実務的だと考えています。

👁 Image

  • Bronze:S3 + Iceberg
  • Silver:S3 + Iceberg(必要に応じてSnowflake連携)
  • Gold:S3 + Iceberg → Snowflake連携

特に Gold層をSnowflakeに寄せることで、BI利用者や業務部門が扱いやすいセマンティックレイヤを提供しやすくなります。
また、場合によってはSilver層も活用してより詳細な分析を実施することが可能となります。
つまり、データ管理とデータ分析の職務分離が可能となります。

主導権の分離で考える

本記事で最も重要なのはここです。

領域 主導
データ実体 AWS
ガバナンス AWS/Snowflake
分析 Snowflake
AI対話 Snowflake

重要なのは製品ではなく、「主導権をどう分離するか」です。
この分離を明確にすることで、データエンジニアリング、BI、AI活用の責任範囲を整理しやすくなり、組織運営の観点でもメリットがあります。

Snowflake Cortex AIがもたらす変化

今後さらに重要になるのがAI活用です。
他のデータプラットフォームと同様にSnowflakeでもAI活用が進んでいます。
Snowflake Cortex AIを活用することで、S3上のIcebergテーブルに自然言語で問い合わせることが可能となります。

つまり、データ基盤は、「SQLを書く基盤」から「対話する基盤」へ進化しています。

今後も様々な面でAI活用が進化していくことが考えられます。
よりAIが使いやすいデータ、所謂AI-Readyのデータを整備することが一つのポイントになると考えています。

まとめ

今回は、AWSのレイクハウス(Apache Iceberg)をSnowflakeと連携する2つのパターンについて整理しました。
近年のデータ活用については、AWS単体にとどまらず、Databricksや今回紹介したようなSnowflakeと連携することも多いです。

先に触れたように重要なのは製品ではなく、「主導権をどう分離するか」です。

データやガバナンス、分析などの主導権をどのサービスが担うかにより、アーキテクチャや設定が変わってきます。

いずれにせよ、重要なのは製品そのものではなく、ユーザに継続して使われるデータ基盤をどのように設計するかという視点だと考えています。
今後は、データをどこに保存するかだけでなく、誰がどのレイヤの責任を持ち、どのようにユーザ価値へつなげるかという観点でアーキテクチャを設計することがより重要になると考えています。

今回の記事が、AWSとSnowflakeの組み合わせを検討している方の参考になれば幸いです。

Discussion

👁 Image