概要
先日、AthenaのEngine Version3以降で、Athenaがサポートするすべてのテーブルフォーマットに対してLakeFormationによるアクセス制御を利用できるようになりました。
https://aws.amazon.com/jp/about-aws/whats-new/2022/11/amazon-athena-support-lake-formation-fine-grained-access-control/
ここにはこれまでLakeFormationとの統合がサポートされていなかったIcebergも含まれています。
これが実際に使えるようになったとのことなので、Icebergテーブルに対してLakeFormationの行レベルセキュリティが利用できるか試してみました。
Iceberg
Icebergは大規模データを扱うためのオープンなテーブルフォーマットで、
- ACIDトランザクションのサポート
- タイムトラベルクエリ
- テーブルデータの最適化
などの特徴があります。
詳細についてはクラスメソッドさんの記事がとても参考になります。
タイムトラベルクエリ
個人的にIcebergでとても面白い機能だと思っているのですが、クエリで時刻を指定することで"指定した時刻"に遡った結果を返してくれます。
SELECT * FROM users_iceberg FOR TIMESTAMP AS OF TIMESTAMP '2022-12-01 00:00:00 UTC';
今回はこのタイムトラベルクエリがLakeFormation経由でも利用できるかを試したいと思います。
準備
Icebergテーブルを作成
以下のようなユーザー一覧テーブルを用意します。
CREATE TABLE sample.users_iceberg (
id string,
name string,
address string,
department string)
LOCATION 's3://example-bucket/iceberg/users'
TBLPROPERTIES (
'table_type'='iceberg',
'format'='parquet'
);
数件のサンプルデータを用意します。
id | name | address | department |
---|---|---|---|
1002 | 山田太郎 | taro@example.com | 開発部 |
1003 | 佐藤二朗 | jiro@example.com | 開発部 |
1004 | 大森花子 | hanako@example.com | 営業部 |
1005 | 林望 | nozomu@example.com | 営業部 |
ここではdepartment
カラムに対して行レベルでの権限分離を行います。
WorkGroupを作成
クエリエンジンにVersion3 を指定したワークグループを作成します。
ちなみにVersion2を指定したワークグループ上で行レベルセキュリティを利用したクエリを実行しようとするAccess Denied
が発生します。
動作確認
この状態で行レベルセキュリティを設定せずに全件クエリを実行すると以下のような結果が取得できます。
行レベルセキュリティを設定
ここから営業部と開発部に分離する権限設定を作成していきます。
IAM Roleを作成
departmentごとの権限でデータにアクセスするためのRoleを準備します。
- sample-lakeformation-dep-dev-role
- sample-lakeformation-dep-sales-role
各Roleには
- AmazonAthenaFullAccess
- AWSLakeFormationDataAdmin
の2つのマネージドポリシーをアタッチしておきます。
LakeFormation権限を付与
必要な権限を付与していきます。
Describe権限を付与
まず両方のRoleがテーブルにアクセスできるようにLF-Tagsを適当に作成します。
そして今回の検証用データベースにこのLF-Tagsをアタッチします。
データベースにタグをアタッチするとデータベース内のテーブルにも推移的にタグがアタッチされます。
各RoleにLF-Tagsに対するデータベース/テーブルのDescribe権限をアタッチします。
こうしておくことで検証に使用するデータベースやテーブルが増えても毎回権限を付ける手間を省略できます。
Data Filterを作成
行レベルで権限分離したSELECT権限を付与するため、Data Filterを作成します。
Data FilterはLF-Tagsを利用することが出来ないため適用対象のテーブルまで明示する必要があります。
開発部用 Data Filter
営業部用 Data Filter
それぞれのRoleに対応するData FilterのSelect権限をアタッチします。
これにより、各RoleでテーブルにSELECT Queryを実行するとFilterが強制的に適用された動作をします。
DataLocation権限を付与
最後にS3にアクセスするためにDataLocation権限を付与します。
まずはData lake locations にs3パスを登録しておきます。
登録したパスに対してData location権限をアタッチします。
検証
動作確認
まずは行レベルセキュリティが機能していることを確認するためにそれぞれのRoleにswitchしてSELECTを実行します。
開発部(sample-lakeformation-dep-dev-role)
営業部(sample-lakeformation-dep-sales-role)
どちらもWHERE句を指定しない全件SELECTですが、Roleによって取得できる行が制限されています。
営業部メンバーを異動させる
タイムトラベルクエリの動作確認をしたいので、Icebergテーブルのデータを以下のクエリで更新します。
UPDATE users_iceberg SET department='開発部' WHERE id='1005';
S3にParquetで保存されているDataLakeのデータに対してUPDATE文が実行できるのも面白いですね。
結果確認
開発部(sample-lakeformation-dep-dev-role)
営業部(sample-lakeformation-dep-sales-role)
更新が反映されていることが確認できます。
タイムトラベル
この状態から、更新前の時間を指定したタイムトラベルクエリを実行します。
開発部(sample-lakeformation-dep-dev-role)
営業部(sample-lakeformation-dep-sales-role)
更新前の各部門のユーザー一覧が取得できていることが確認出来ます。
結論
LakeFormationの行レベルセキュリティを適用したRoleからIcebergテーブルに対してタイムトラベルクエリを実行することができました。
RDSなどにあるマスタデータソースからDataLake上に複製したディメンションテーブルを作成しておき、このディメンションテーブルに対してタイムトラベルクエリを活用することで月次断面での分析などがやりやすくなるのではと思っています。
行レベルセキュリティが必要な状況でもこのタイムトラベルクエリが利用できるようになったことは、LakeFormationの活用の幅が1つ広がったのではないでしょうか。