AWS Lake Formationの外部共有を試してみた
こんにちは!DA(データアナリティクス)事業本部 サービスソリューション部の大高です。
AWS Lake Formationでは、データカタログを外部アカウントへ共有し、共有先アカウントから共有元アカウントのデータに対してAthenaからクエリを実行することができます。
今回、このAWS Lake Formationの外部アカウント共有を試してみたのでまとめたいと思います。
やりたいこと
まず、AWS Lake Formationで外部アカウント共有をしたいなら、こちらの動画が必見の動画だと思います。
以下はこちらの動画で紹介されているクロスアカウントアクセスのワークフロー図です。
今回は、このワークフローと同じく、データカタログを別アカウントに共有してAthenaでクエリを実行したいです。 基本的にこの動画の流れに沿って実施します。
前提条件
データやデータベース、テーブルの事前準備、および、権限管理については下記のエントリで記載したものを利用します。郵便番号についてのテーブルを、Tag-based Access Control(以下、TBAC)で管理しているものです。
今回は、このTBACで管理している特定のカラムだけを、共有先のAWSアカウントからAthenaでSELECTしたいと思います。
また、Lake Formationによる権限管理も以下のエントリに記載の通りに設定をしています。
共有元、および、共有先アカウントでのLake Formationの操作は、すべて「Lake Formation Admin(Lake Formationの管理者ユーザ)」で実施しています。実際の共有データカタログの利用時には、共有先アカウントで細かい権限制御を実施することになると思いますが、今回は主題から外れるのでLake Formation Adminを利用しています。
共有元アカウントでの設定
前提条件に記載のとおり、データベースとテーブルは準備済みなので、共有元アカウントではGlue Catalogの設定から進めていきます。
Glue Catalogの設定
TBACを利用して共有を掛けたい場合には、下記のドキュメントに記載のとおりGlue Catalogのリソースポリシーにポリシーを追加する必要があります。
今回は「現行のポリシー設定は無い」という前提で、下記のポリシーを追加します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "glue:*" ], "Principal": { "AWS": [ "<recipient-account-id>" ] }, "Resource": [ "arn:aws:glue:<region>:<account-id>:table/*", "arn:aws:glue:<region>:<account-id>:database/*", "arn:aws:glue:<region>:<account-id>:catalog" ], "Condition": { "Bool": { "glue:EvaluatedByLakeFormationTags": true } } } ] }
recipient-account-id
は、共有先AWSアカウントの12桁のID、region
およびaccount-id
は、共有元AWSアカウントのリージョンと12桁のIDを指定します。
注意点
2021/08現在、AWSの管理コンソールから上記ポリシーを設定しようとすると下記のエラーが発生します。
{"service":"AWSGlue","statusCode":400,"errorCode":"InvalidInputException","requestId":"2223b225-62e2-4eb5-bd29-f7e6ab175a2e","errorMessage":"EnableHybrid must be set to TRUE to allow policy hybrid.","type":"AwsServiceError"}
エラーメッセージに記載されているEnableHybrid
のパラメータは管理コンソールの画面からは設定できないので、AWS CLIやboto3のAPIで設定します。例として、AWS CLIの場合は、以下のようなコマンドになります。
$ aws --profile foo-bar \ glue put-resource-policy \ --policy-in-json file://./gule-access-policy.json \ --enable-hybrid TRUE
Data lake locationsの設定
次に、Data lake locationの設定を行います。これは下記の図の「3. Get temporal credential」において、AWS Lake Formationのサービスリンクロールを経由してS3へアクセスを行うことになるのですが、この際のアクセス権限を与えるための設定となります。
この設定は、AWS Lake Formationの管理コンソールメニュー「Register and Ingest > Data lake locations」から「Register location」をクリックして権限を付与していきます。
ロケーションの登録画面では、Lake Formationのデータベース作成時に指定したS3バケットと、IAMロールを指定します。今回は、デフォルトのAWSServiceRoleForLakeFormationDataAccess
を設定しますが、サービスリンクロールを事前に作成しておいて、指定しても構いません。
なお、最初はデータベース作成時に指定したS3パスを指定していたのですが、最後のAthenaからのクエリ実行で参照権限エラーが発生したため、今回はS3バケットを指定しています。
Data permissionsの設定
最後に、共有先AWSアカウントへ該当タグを付与したリソースに対するアクセス許可を与えます。
AWS Lake Formationの管理コンソールメニュー「Permissions > Data permissions」から「Grant」をクリックして権限を付与していきます。
Principals
External accounts
を選択し、共有先のAWSアカウントIDを入力します。注意点として、入力後にプルダウンにNo matches
と表示されますが、無視してEnterキーを2回入力します。すると、入力したAWSアカウントIDが入力エリアの下部に表示されます。
LF-Tags or catalog resources
ここでは、TBACで共有したいのでResources matched by LF-Tags
を選択します。選択したら、権限設定をしたいタグとその値を選択します。
なお今回は扱いませんが、リソース名ベースの権限管理を行う場合は自動でRAM(Resource Access Manager)の設定がされ、共有先アカウントに承認依頼が表示されるようになります。
Database permissions
今回、データベースは共有しないので、そのままとします。
Table and column permissions
タグ付けをした特定のカラムを共有先AWSアカウントから参照させたいので、Select
とDescribe
だけ権限付与します。
最後に「Grant」をクリックして権限付与の完了です。
共有先アカウントでの設定
次に、共有先アカウントでの設定を行います。まずはAWSアカウントを切り替えて、共有したテーブルが見えていることを確認しましょう。(Lake Formation Adminでないと見えないことに注意します)
確認できたら、更に設定を進めます。
Linked Tableの作成
共有したテーブルが見えているので、このテーブルに対してクエリをかければ良さそうに見えますが、実はこのテーブルにはクエリ実行はできません。
共有されたテーブルに対して、更に「Linked Table」というテーブルを作成する必要があります。「Data catalog > Tables」の「Create table」から「Linked Table」を作成しましょう。
Resource link
を選択し、適宜、テーブル名を付けて作成します。データベースは既存のdefault
データベースを利用するようにしました。Shared table
には共有したテーブルken_all
を指定します。
最後に「Create」をクリックして作成完了です。
Athenaでのクエリ実行
では、実際にAthenaでクエリ実行してみましょう。
該当テーブルを選択し「Actions > View data」を選択するとAthenaのコンソール画面が開きます。
無事に、共有したテーブルデータがSELECTできました!
まとめ
以上、AWS Lake Formationの外部共有を試してみました。
権限管理の考え方がDWHに近くなっているので少し設定に癖がありますが、うまく使いこなせるようになると今回のような外部共有も活用できるようになるかなと思いました。精進します。
どなたかのお役に立てば幸いです。それでは!