AWS Clean Roomsで簡単かつ安全に、加工済みデータをアカウント間連携してみた!

一般提供されたAWS Clean Roomsでデータクリーンルームを作成し、アカウント間の安全なデータ連携をするための設定について確認しました。
2023.06.19

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

今年3月にAWS Clean RoomsがGAになりましたが、改めて一般提供版で使い方を確認してみたのでまとめました。

この記事で確認している内容は、基本的にはパブリックプレビュー時期に以下の記事で確認したものと同じです。プレビュー版で試した際の操作と大きな違いは特になかったため、プレビュー版で検証されていた方は同じように使って頂けると思います。

AWS Clean Roomsとは?

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

コラボレーションするAWSアカウントはAWS Clean Roomsのコラボレーションにて指定できます。コラボレーションには、どのようなクエリを許可するかという分析ルールを設定したテーブルを関連付け、アカウントを跨ぎつつもデータ取得を制御したデータ連携が可能になります。

検証した仕組みの全体像

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

試した構成の全体像

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

事前に用意しておいた以下の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

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

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

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

コラボレーション作成3

クエリログ記録・暗号コンピューティング・コラボレーションタグは設定せずに進みました。

メンバーシップを設定でどのタイミングでコラボレーションに参加できるか選べました。今回ははい、今すぐメンバーシップを作成してご加入くださいを選びました。

コラボレーション作成4

確認と作成で入力内容を確認した後、コラボレーションが作成されました。

コラボレーション作成5

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

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

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

新しいテーブルを設定

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

新しいテーブルを設定

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

設定済みのテーブル

次に、赤枠箇所から、分析ルールを設定します。

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

検索ができるよう、テーブルへ分析ルールを設定します。手順3で引き続き、分析ルールを設定を押します。

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

分析ルールの設定1

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

分析ルールの設定2

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

分析ルールの設定3

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

分析ルールの設定4

続いて赤枠箇所から、コラボレーションへの関連づけを行います。

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

設定したテーブルをコラボレーションに関連付けます。手順4に引き続き、テーブルを関連付けるを押します。

関連づけるテーブルを選択し、サービスアクセスに手順1で作成したサービスロールを選択しました。

テーブルの関連付け設定

テーブルを関連付けるをクリックして作業を完了しました。

コラボレーションの画面から確認すると、以下のように関連付けができました。

関連付けたテーブル

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

ここからはコンシューマーのアカウントでの操作です。プロデューサーのアカウントで作成され招待されたコラボレーションに参加します。

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

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

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

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

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

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

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

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

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

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

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

結果の保存設定

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

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

結果設定を設定1

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

結果設定を設定2

フォーマットは記事執筆時点でCSVとParquetが選択できました。特に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

無事結果が取得できましたが、Parquetを指定したからか結果のプレビューはできませんでした。

成功した検索結果_Parquet

クエリ結果設定で、結果フォーマットをCSVにしてもう一度実行すると、今度はプレビューが表示されました。

成功した検索結果_CSV

やはり初回実行時はクエリの実行にしばらく時間がかかるようでした。2回目以降はそうでもありませんでした。

クエリの実行時間

失敗するパターン

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

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

select 
  distinct sepal_length
from iris_quality_check

失敗した検索結果

リソースの削除

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

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

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

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

コンシューマー側メンバーシップの削除

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

コラボレーションの削除

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

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

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

テーブルの削除

最後に

今回はAWS Clean Roomsの基本的な操作内容を紹介しました。

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

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

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

プレビュー時点でも非常に完成度が高いUIだなと思っていましたが、一般提供版はさらに一部UIに改善が入った印象でした。とはいえ操作はほぼプレビュー版と同じだったので、プレビュー版でいろいろ試行錯誤されていた方はそのまま使って頂けると思います。

また、クエリの画面で一部写っていましたが、Analysis Builderのような追加機能も提供されており、SQLを使わないユーザーに対しても使ってもらいやすいよう工夫がされておりとても良かったです。この機能については『AWS Clean RoomsのAnalysis Builderを使ってみた』でご紹介しました。このような機能改善がどんどん追加されているのもとてもいいですね。