AWS Clean Rooms (プレビュー)で、あっという間に加工済みデータをアカウント間で連携してみた!

簡単にアカウント間の安全なデータ共有が実現できます!
2023.03.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データアナリティクス事業本部の鈴木です。

AWS re:Invent 2022で発表されたAWS Clean Rooms(プレビュー)ですが、東京リージョンでも利用できるようになっていたので、試してみた結果をご共有します。

検証した画面例を交えて、どのようにAWS Clean Rooms (プレビュー)でアカウント間のデータ連携ができるか分かるようにまとめてみました。

AWS Clean Rooms(プレビュー)とは?

AWSにアクセスできる他の企業のメンバーとコラボレーションして、顧客データの分析を行うことができるClean Roomsをわずかな時間で簡単に構築できるサービスになります。

DevelopersIOでは、re:invent2022の発表時の速報と紹介セッションの内容を記事として取り上げていましたので参考にして下さい。

検証した仕組みの全体像

今回検証してみた仕組みに登場する要素を整理してみました。

試した構成の全体像

※ 図は整理用に私が作成しただけなので、もし不正確なところがあればご容赦ください。

事前に用意しておいた以下の2アカウントで検証しました。

  • データ提供側のアカウント
  • データ分析側のアカウント

データ提供側のアカウントではS3バケットにデータを用意し、Glueテーブルを作成しておきました。AWS Clean Roomsでデータ分析側のアカウントとのコラボレーションを作成し、そのテーブルを設定して分析ルールも設定しておきました。データ分析側のアカウントからコラボレーションに参加し、AWS Clean Roomsのコンソールから検索できるか確認しました。

後ほど2つのアカウントのコンソールで実際に操作をしていきますが、ライトモードの画面がデータ提供側のアカウント、ダークモードの画面がデータ分析側のアカウントです。

各アカウントのコラボレーションメンバー用のIAMロールについては開発者ガイドの以下の項目に記載がありますが、今回は事前に準備した十分な権限があるロールで試しました。

検証手順の紹介

AWS Clean Roomsのセットアップ例は、プレビュー版の開発者ガイドに記載があるので、今回はこの手順を参考に進めました。

今回は以下の手順で進めました。

  1. データ提供側のアカウントで、AWS Clean Rooms用のサービスロールを作成する。
  2. データ提供側のアカウントで、コラボレーションを作成する。
  3. データ提供側のアカウントで、クエリするデータテーブルを準備する。
  4. データ提供側のアカウントで、設定したテーブルをコラボレーションに関連付ける。
  5. データ提供側のアカウントで、設定したテーブルへの分析ルールを設定する。
  6. データ分析側のアカウントで、メンバーシップを作成し、コラボレーションに参加する。
  7. データ分析側のアカウントで、クエリを発行し、データを取得する。

一部入れ替わっている手順がありますが、できるだけ開発者ガイドに出てくる順に沿うようにしました。また、AWSへのサインアップなど一部手順はスキップしています。

やってみる

手順1: AWS Clean Rooms用のサービスロールを作成する

まずAWS Clean Rooms用のサービスロールを作成しました。必要な権限は、開発者ガイドのCreate a service role for AWS Clean Roomsに記載があるので、これを参考にしました。

以下のCloudFormationテンプレートを実行し、IAMロールを作成しました。

AWSTemplateFormatVersion: "2010-09-09"
Description: Creating Service Role for Clean Rooms 

Parameters:
  S3BucketName:
    Description: Bucket Name for Target Data.
    Type: String
  S3Prefix:
    Description: Prefix for Target Data Under S3 Bucket.
    Type: String
  GlueDatabaseName:
    Description: Glue Database for Target Data.
    Type: String
  GlueTableName:
    Description: Glue Table for Target Data.
    Type: String

Resources:
  IAMRoleForCleanRoomsService:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Sid: RoleTrustPolicyForCleanRoomsService
            Effect: Allow
            Principal:
              Service: cleanrooms.amazonaws.com
            Action: "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: CleanRoomsServicePolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: NecessaryGluePermissions
                Effect: "Allow"
                Action: [
                  "glue:GetDatabase",
                  "glue:GetDatabases",
                  "glue:GetTable",
                  "glue:GetTables",
                  "glue:GetPartition",
                  "glue:GetPartitions",
                  "glue:BatchGetPartition"
                ]
                Resource: [
                  !Sub "arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/${GlueDatabaseName}",
                  !Sub "arn:aws:glue:${AWS::Region}:${AWS::AccountId}:table/${GlueDatabaseName}/${GlueTableName}",
                  !Sub "arn:aws:glue:${AWS::Region}:${AWS::AccountId}:catalog"
                ]
              - Sid: NecessaryS3BucketPermissions
                Effect: "Allow"
                Action: [
                  "s3:GetBucketLocation", 
                  "s3:ListBucket"
                ]
                Resource: [
                  !Sub "arn:aws:s3:::${S3BucketName}"
                ]
                Condition: 
                  StringEquals:
                    's3:ResourceAccount': [
                      !Sub "${AWS::AccountId}"
                    ]
              - Sid: NecessaryS3ObjectPermissions
                Effect: "Allow"
                Action: [
                  "s3:GetObject"
                ]
                Resource: [
                  !Sub "arn:aws:s3:::${S3BucketName}/${S3Prefix}/*"
                ]
                Condition: 
                  StringEquals:
                    's3:ResourceAccount': [
                      !Sub "${AWS::AccountId}"
                    ]

S3バケットおよびGlueの設定についてはパラメータで渡せるようにしています。S3バケット名とプレフィクスは、分析対象のデータがあるところを指定しました。Glueデータベースとテーブルは、そのデータを検索できるようにあらかじめデータベースとテーブルを作成しておき、その名前を入力しました。

なお、今回は以前執筆したAWS Glue Data Quality(プレビュー) をAWS Glueコンソールから試してみよう!で利用したテーブルを流用しました。このテーブルにはUCI Machine Learning RepositoryのIris Data Setのデータ(4KB程度)が入っています。

データは下記のリンクで提供されています。

  • https://archive.ics.uci.edu/ml/datasets/iris

手順2: コラボレーションを作成する

コラボレーションを作成します。まず、AWS Clean Roomsのコンソールでコラボレーションを押します。

コラボレーション作成1

コラボレーションを作成を押します。

コラボレーション作成2

コラボレーションを作成画面で、名前・説明を入力しました。

また、自アカウントを含むメンバー表示名の設定とメンバー追加を行いました。今回はメンバー2としてデータ分析側のアカウントを設定しました。これはメンバー2の欄のメンバーAWSアカウントIDに該当するAWSアカウントIDを入力することで設定ができます。(記事ではセキュリティ上、見えないように加工しています。)

メンバー能力の欄では、クエリを実行して結果を受け取ることができるメンバーを指定できます。メンバー2のアカウントでデータを取得できるようにしたいので、member2を設定しておきます。

コラボレーション作成3

クエリログ記録と暗号コンピューティングは今回はチェックを入れずに進みました。

問題なければコラボレーションを作成および参加をクリックします。

この設定をもってコラボレーション相手のアカウントのAWS Clean Roomsに招待が送られるので、再度問題ないか確認のポップアップが表示されます。問題なければコラボレーションを作成および参加をクリックします。

これでコラボレーションが作成されました。

コラボレーション作成結果

手順3: クエリするデータテーブルを準備する。

次にクエリするデータテーブルを準備していきます。これはGlueデータカタログのテーブルをAWS Clean Roomsに登録するような作業になります。先に記載の通り、今回はGlueデータカタログに既にテーブルを作成している前提で記載します。

AWS Clean Roomsのコンソールで、設定済みのテーブルをクリックし、新しいテーブルを設定を押します。

テーブルの作成

新しいテーブルを設定画面で、設定したいAWS Glueテーブルを選び、コラボレーションで検索を許可する列を指定します。コラボレーションで検索を許可する列欄ではカスタムリストを選べば検索を許可するカラムを指定できるようですが、今回はあまり気にせずすべての列を選んでみました。

分かりやすいよう、設定済みのテーブルの詳細も入力しておきます。名前とテーブルの説明を記載しました。後ほど画面を掲載しますが、分析側アカウントでもこの内容を確認することができるので重要です。

新しいテーブルを設定

問題なければ新しいテーブルを設定を押し、以下のように設定ができました。

設定済みのテーブル

なお、概要のクエリ可能欄にアラートが表示されていますが、このテーブルにコラボレーションから検索を実行するためにはさらに以下の作業が必要になります。これらは後の手順で実施しました。

  • テーブルをコラボレーションに関連づける
  • テーブルに分析ルールを設定する

手順4: 設定したテーブルをコラボレーションに関連付ける

設定したテーブルをコラボレーションに関連付けます。手順2で作成したコラボレーションを開き、テーブルを関連付けるを押します。

テーブルの関連付け

関連づけるテーブルを選択し、サービスアクセスに手順1で作成したサービスロールを選択しました。この画面で新しいサービスロールを作成して設定することも可能なようでした。

テーブルの関連付け設定

また、ポリシー文書を表示で必要なロールの確認もできるようだったので、より複雑なケースでサービスロールを作成に頭を悩ませたときは、この表示をみるとヒントになるかもしれません。

ポリシー文書の表示例

テーブルを関連付けるをクリックして、以下のように関連付けができました。

関連付けの結果

分析ルールは設定していないので、クエリ可能欄にまだアラートが出ていることが分かります。また、分析側のアカウントでまだコラボレーションに参加していないので、メンバーの1/2人がアクティブになっています。つまり、コラボレーションの参加を待たなくても作業を進めてしまえることが分かります。

手順5: テーブルへの分析ルールを設定する

検索ができるよう、テーブルへ分析ルールを設定します。設定済みのテーブルから分析したいテーブルを開き、分析ルールを設定を押します。

分析ルールの設定1

分析ルールの設定2

ステップ1でタイプを選択します。今回は集約関数なしで弾かれるかみてみたかったので集約を選択しました。作成方法はガイドフローを選びました。JSONエディタを選ぶと、JSONファイルで設定を読み込むこともできるようでした。

分析ルールの設定3

ステップ2のクエリコントロールを指定画面では、クエリで許可する細かな操作について設定できました。

分析ルールの設定4

ステップ3のクエリ結果コントロールを指定画面では、クエリ結果が返却される条件について設定できました。

分析ルールの設定5

ステップ4で設定を確認し、分析ルールの設定を完了します。

手順6: メンバーシップを作成し、コラボレーションに参加する

ここからは分析側のアカウントでの操作です。データ提供側のアカウントで作成され招待されたコラボレーションに参加します。

コラボレーションから参加可能タブを開き、招待されたコラボレーションを開きました。

コラボレーションへの参加1

招待されたコラボレーションの画面から、メンバーシップを作成を押しました。

コラボレーションへの参加2

招待の内容に間違いがないか確認のポップアップが出るので、内容を確認し、メンバーシップを作成を押してコラボレーションに参加しました。

コラボレーションへの参加3

これでコラボレーションに参加し、データを検索できるようになりました。

コラボレーションへの参加4

手順7: クエリを発行し、データを取得する

クエリエディタから検索をしてみます。

結果の保存設定

最初に、検索結果を保存する場所の設定をする必要があります。

クエリエディタの右上のアクションから結果設定を設定を押しました。

結果設定を設定

S3の送信先を設定し、保存のフォーマットを選択し、保存しました。

クエリ結果設定

フォーマットはプレビュー段階でもCSVとParquetが選択でき、後続のAthenaなどで検索する際にも便利なことが分かります。

成功するパターン

今回は手順5でAVG関数による集約を許可しているので、まずは試してみました。

以下のSQLをクエリエディタから実行しました。

select 
  AVG(sepal_length) as sepal_length_avg,
  AVG(sepal_width) as sepal_width_avg,
  AVG(petal_length) as petal_length_avg,
  AVG(petal_width) as petal_width_avg,
  class
from iris_quality_check
group by class

無事結果が取得できました。

成功した検索結果

コラボレーションに参加して一番最初に実行したクエリだったからか、結果を取得するのに340秒かかり、実行時間が長く感じましたが、これは2回目以降はるかに短い時間(30秒弱)で完了することが分かりました。

3回検索した結果

失敗するパターン

分析ルールに沿わないので失敗が期待されるSQLも実行してみました。

以下のように集約しないままSELECTするSQLを実行すると、指定したカラムはSELECTが許可されていない旨のエラーが出て確かに失敗しました。

集約しないケース

リソースの削除

一通り確認したいことが検証できたので、削除についても確認しました。

以下のリソースを削除していきました。

  1. データ分析側のアカウントのメンバーシップ
  2. データ分析側のアカウントのコラボレーション
  3. データ分析側のアカウントの設定済みテーブル
  4. データ分析側のアカウントのサービスロールのCloudFormationスタック

データ分析側のアカウントのメンバーシップは、コラボレーションの画面のアクションからメンバーシップを削除で削除できました。

メンバーシップを削除

コラボレーションは、データ提供側のアカウントのコラボレーションの画面のアクションからコラボレーションを削除で削除できました。

コラボレーションを削除

コラボレーションは、データ提供側のアカウントの利用できなくなりましたタブから削除したものを確認できました。

削除したコラボレーション

テーブルも設定済みのテーブルから削除したいテーブルを開き、削除から削除できました。

テーブルの削除

料金について

実際に触ってみて改めて料金について気になったので調べてみました。料金は製品ページから確認できます。

記事執筆時点では、東京リージョンではCRPU時間あたり$0.865で、コンピューティングリソースあたりの課金になります。コンソールがAthenaに似ているのでなんとなくスキャン量による課金かと思い込んでいましたが、そうではないので記憶に留めておくとよさそうです。

より詳細には以下のように記載がありました。

With AWS Clean Rooms, you only pay for the compute capacity of queries that you run. AWS Clean Rooms automatically scales up or down to meet your query workload demands and shuts down during periods of inactivity, saving you administration time and costs. AWS Clean Rooms measures compute capacity in Clean Rooms Processing Units (CRPUs). You pay for the workloads you run in CRPU-hours on a per-second basis (with a 60-second minimum charge). The base capacity for AWS Clean Rooms collaborations is 32 CRPUs—this capacity can scale up or down automatically based on usage patterns. AWS Clean Rooms pricing varies by Region.

※料金ページ(https://aws.amazon.com/jp/clean-rooms/pricing/)より2023/3/6に転記しました。

最後に

今回はAWS Clean Rooms(プレビュー)ですが、東京リージョンでも利用できるようになっていたので、検証した内容をご紹介しました。

ドキュメントやコンソールにとても丁寧に情報が記載されており、ほとんど詰まることなくあっという間にコラボレーションを設定することができました。製品ページでも数分で作成できることを謳っていますが、まさにその通りだなと驚きました。

検索結果はCSVだけではなくParquetでも保存でき、後続にAthneaなどの検索機能を配置して使うようなユースケースに気を配っている点もとても良いところでした。

今回は分析ルールはざっくりと設定してしまいましたが、細かく設定ができる点も大きなポイントかと思います。

執筆時点ではプレビュー中ですが、ご興味がある方はぜひ試してみて頂ければと思います。この記事が参考になりましたら幸いです。