AWS Lake Formationを有効にした時の既存リソース(Glue,S3)へのアクセスについて整理してみる

AWS Lake Formationを有効にした時の既存リソース(Glue,S3)へのアクセスについて整理してみる

Clock Icon2025.02.05

はじめに

データ事業本部ビッグデータチームのkasamaです。
今回はAWS Lake Formationを有効にした時の既存リソース(Glue、S3)へのアクセスがどのようになるか自分の理解も含めて整理してみたいと思います。

概要

AWS_Lake_Formation_既存リソース検証

検証内容としては、以下の3種類のIAM Roleがあるときに、AWS Lake FormationがLake Formationモード、もしくはハイブリッドアクセスモードの時にどのようなアクセス制御となるかを検証したいと思います。

  • Admin権限を持つIAM Role
  • 既存リソース(Glue、S3)に対する直接アクセス権限を持つIAM Role
  • 既存リソース(Glue、S3)に対する直接アクセス権限を持たない and Lake Formationアクセス権限を持つIAM Role

AWS Lake Formationモード

AWS Lake Formationモードの場合は、Glue、S3に対して直接的なIAM ポリシーがあるだけではアクセスできず、Lake Formation上でのアクセス許可が必要となります。これは既存IAMリソースに対しても影響があります。

https://docs.aws.amazon.com/ja_jp/lake-formation/latest/dg/how-it-works.html

AWS Lake Formationハイブリッドアクセスモード

AWS Lake Formationハイブリッドアクセスモードの場合、既存のIAM RoleはIAM Policyの権限でアクセスでき、オプトインしたIAM Roleのみ、Lake Formationでのアクセスとなります。

https://docs.aws.amazon.com/ja_jp/lake-formation/latest/dg/hybrid-access-mode.html

結論

  • AWS Lake Formationモードの場合
No. IAMロール Glue許可 (Data Permissions) S3許可(lakeformation:GetDataAccess) Athena参照
1 Admin Role ✅ OK
2 Admin Role × ❌ NG
3 直接アクセス権限あり Role × ❌ NG
4 直接アクセス権限あり Role × × ❌ NG
5 直接アクセス権限なし ✅ OK
6 直接アクセス権限なし × ❌ NG
  • AWS Lake Formationハイブリッドアクセスモードの場合
No. IAMロール Glue許可 (Data Permissions) S3許可(lakeformation:GetDataAccess) Athena参照
7 Admin Role ✅ OK
8 Admin Role × ❌ NG
9 直接アクセス権限あり Role × ✅ OK
10 直接アクセス権限あり Role × × ❌ NG
11 直接アクセス権限なし ✅ OK
12 直接アクセス権限なし × ❌ NG

AWS Lake Formationモードの場合は、AWS Lake Formation上で、Glue、S3両方のアクセス権限を許可しないとアクセスできません。
AWS Lake Formationハイブリッドアクセスモードの場合は、AWS Lake Formation上で、Glueへのアクセス許可は必要ですが、S3については直接のアクセス権限があればAthenaで参照することが可能です。(No.9のケース)
そのため、既存リソースへの影響を最小限にしたい場合は、ハイブリッドアクセスモードからLake Formationを導入してみると良いと思いました。
一方で、GlueのZero ETL統合やAmazon S3 Tablesをハイブリッドアクセスモードで使用できるかどうかはまだ不明なため、その辺りは引き続き検証していきたいと思います。

事前準備

事前準備として以下の作業を行います。

  • S3 Bucket作成、csv配置
  • 検証用IAM Role作成
  • Glue database, table作成

上記の作業は、AdministratorAccessポリシーを持つIAM Roleで実施することを前提としています。

使用するリソースについてはGithubリポジトリにも格納しています。

https://github.com/cm-yoshikikasama/blog_code/tree/main/49_lakeformation_exist_resource_test

S3 Bucket作成、csv配置

まずは、AWS Management Console上で、試験用データを配置するS3 BucketとAthenaクエリの結果ファイルを保存するS3 Bucketを作成します。

personal_info.csv
employee_id,first_name,last_name,department,salary,hire_date
1001,John,Smith,Sales,50000,2022-01-15
1002,Mary,Johnson,IT,60000,2021-06-20
1003,Robert,Williams,HR,45000,2023-03-10
1004,Sarah,Brown,Sales,52000,2022-08-01
1005,Michael,Davis,IT,65000,2021-04-15
1006,Lisa,Miller,HR,47000,2023-01-20
1007,David,Wilson,Sales,51000,2022-11-30
1008,Jennifer,Jones,IT,63000,2021-09-10
1009,James,Taylor,HR,46000,2023-02-28
1010,Emily,Anderson,Sales,53000,2022-05-15

試験用データを配置するS3 Bucketの以下のパスにファイルを格納します。

s3://<任意のBucket名>/cm_kasama_hr_employee/personal_info/personal_info.csv

次に任意のBucket名で、Athenaクエリ結果ファイルを保存するS3 Bucketを作成し、IAM Roleごとの保存先パスを作成します。

aws s3 ls s3://<任意のBucket名>/
                           PRE admin/
                           PRE hr-restrict/
                           PRE hr/

検証用IAM Role作成

検証用のIAM Roleをymlファイルで作成します。

IAM.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: IAM Roles and Policies for HR Reader

Parameters:
  UserArn:
    Type: String
    Description: IAM User ARN who can assume this role
  AthenaQueryBucketName:
    Type: String
    Description: S3 bucket name for Athena query results
  LakeformationBucketName:
    Type: String
    Description: S3 bucket name for Lake Formation data
  RolePrefixName:
    Type: String  
    Description: Role prefix name

Resources:
  HRReaderRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${RolePrefixName}-hr-data-access-with-iam-policy
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref UserArn
            Action: sts:AssumeRole
            Condition:
              Bool:
                aws:MultiFactorAuthPresent: 'true'
      Policies:
        - PolicyName: HRReaderPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - glue:GetDatabases
                  - glue:GetTables
                  - glue:GetTable
                  - glue:GetPartitions
                  - glue:GetDatabase
                Resource: '*'
              - Effect: Allow
                Action:
                  - athena:StartQueryExecution
                  - athena:GetQueryExecution
                  - athena:GetQueryResults
                  - athena:GetWorkGroup
                  - athena:ListWorkGroups
                Resource: '*'
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:GetObject
                  - s3:ListBucket
                  - s3:GetBucketLocation
                Resource:
                  - !Sub arn:aws:s3:::${AthenaQueryBucketName}
                  - !Sub arn:aws:s3:::${AthenaQueryBucketName}/hr/*
              - Effect: Allow
                Action:
                  - s3:ListBucket
                  - s3:GetObject
                Resource:
                  - !Sub arn:aws:s3:::${LakeformationBucketName}
                  - !Sub arn:aws:s3:::${LakeformationBucketName}/*
              - Effect: Allow
                Action:
                  - s3:ListAllMyBuckets
                Resource: '*'

  HRReaderRestrictRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${RolePrefixName}-hr-data-access-with-lakeformation
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref UserArn
            Action: sts:AssumeRole
            Condition:
              Bool:
                aws:MultiFactorAuthPresent: 'true'
      Policies:
        - PolicyName: HRReaderRestrictPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - glue:GetDatabases
                  - glue:GetTables
                  - glue:GetTable
                  - glue:GetPartitions
                  - glue:GetDatabase
                Resource: '*'
              - Effect: Allow
                Action:
                  - athena:StartQueryExecution
                  - athena:GetQueryExecution
                  - athena:GetQueryResults
                  - athena:GetWorkGroup
                  - athena:ListWorkGroups
                Resource: '*'
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:GetObject
                  - s3:ListBucket
                  - s3:GetBucketLocation
                Resource:
                  - !Sub arn:aws:s3:::${AthenaQueryBucketName}
                  - !Sub arn:aws:s3:::${AthenaQueryBucketName}/hr-restrict/*
              - Effect: Allow
                Action:
                  - lakeformation:GetDataAccess
                Resource: '*'
              - Effect: Allow
                Action:
                  - s3:ListAllMyBuckets
                Resource: '*'

このymlファイルをAWS Management ConsoleからCloudFormationスタックのテンプレートとして、デプロイします。
その際のパラメータはそれぞれ以下を入力します。

  • UserArn: 自分のIAMユーザーARNを入力
  • AthenaQueryBucketName: 先ほど作成したAthenaクエリバケット名を入力
  • LakeformationBucketName: 先ほど作成した試験用データ格納バケット名を入力
  • RolePrefixName: IAM Roleのprefixとなる任意の値を入力

UserArnについては、私はIAM UserからスイッチロールしてIAM Roleへアクセスする形になるので、IAM UserのARNを記載する形としています。こちらはご自身の環境に合わせていただければと思います。

それぞれのIAM Roleですが、hr-data-access-with-iam-policyについては、Lake Formationの権限を介さずともGlue、S3へアクセスできるようにポリシーを付与しています。
hr-data-access-with-lakeformationについては、LakeformationBucketへのアクセス権限はなく、lakeformation:GetDataAccess policyを付与することで、Lake Formation経由でGlue、S3へアクセスするIAM Roleとなっています。

Glue database, table作成

Athena上で以下のSQLをそれぞれ実行し、database、tableを作成します。

employee.sql
-- データベース作成
CREATE DATABASE IF NOT EXISTS cm_kasama_hr_employee;
-- テーブル作成
CREATE EXTERNAL TABLE cm_kasama_hr_employee.personal_info ( 
	employee_id INT, 
	first_name STRING, 
	last_name STRING, 
	department STRING, 
	salary INT, 
	hire_date DATE
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION 's3://<任意のBucket名>/cm_kasama_hr_employee/personal_info/'
TBLPROPERTIES ('skip.header.line.count'='1');

AWS Lake Formationモード検証

AWS Lake Formationモード設定

まずは、AWS Lake Formationモードに設定します。作業としては以下になります。

  • Admin RoleをData lake administratorsに登録

Screenshot 2025-02-04 at 21.58.17

  • Data lake locationsにLake Formationでのアクセス管理としたいS3を登録

Screenshot 2025-02-04 at 21.58.49

この状態でS3はLake Formationモードになります。直接S3 Bucketを参照する方法以外は、lakeformation:GetDataAccess policyがないとアクセスできません。

また、Lake Formationモード前に作成されたリソースは、Data PermissionsでPrincipal IAMAllowedPrincipalsに対し、All権限が付与されています。このアクセス許可がデータベースまたはテーブルに存在する場合、アカウント内のすべてのプリンシパルが、 AWS Glueの IAM プリンシパルポリシーを介してリソースにアクセスできるようになります。
つまり先ほどの表でいうAWS Lake FormationモードかつGlue許可 (Data Permissions)の状態です。
https://docs.aws.amazon.com/ja_jp/lake-formation/latest/dg/lf-permissions-reference.html

Screenshot 2025-02-04 at 22.18.58

No.1,3,5検証

  • No.1 (Admin Role)
    Admin権限なので、Glueへのアクセス権限はあり、lakeformation:GetDataAccess policyでS3へもアクセスできています。
    Screenshot 2025-02-04 at 22.29.45

  • No.3 (直接アクセス権限あり Role)
    Glueへの権限はありますが、lakeformation:GetDataAccess policyがないのでアクセスは失敗します。
    Screenshot 2025-02-04 at 22.30.27
    ただ、S3への直接アクセス権限はあるので、ファイルを直接参照することは可能です。
    Screenshot 2025-02-04 at 22.40.34

  • No.5 (直接アクセス権限なし Lake Formation権限あり Role)
    Glueへの権限はあり、lakeformation:GetDataAccess policyでS3へもアクセスできています。
    Screenshot 2025-02-04 at 22.30.46

No.2,4,6検証

先ほどの表で言うAWS Lake FormationモードかつGlue許可 (Data Permissions)×の状態に設定するために、Data permissionsIAMAllowedPrincipalscm_kasama_hr_employeeに対するall権限をrevokeしました。また、Admin Roleに対しても作成したdatabase,table,columnの権限をrevokeしました。この状態でそれぞれ確認します。

Screenshot 2025-02-05 at 7.15.18
Screenshot 2025-02-05 at 7.25.44

  • No.2 (Admin Role)
    Glueへの権限が無く失敗します。
    Screenshot 2025-02-05 at 7.27.08
  • No.4 (直接アクセス権限あり Role)
    Glueへの権限が無く失敗します。
    Screenshot 2025-02-05 at 7.31.13
  • No.6 (直接アクセス権限なし Lake Formation権限あり Role)
    Glueへの権限が無く失敗します。
    Screenshot 2025-02-05 at 7.31.34

AWS Lake Formationハイブリッドアクセスモード検証

ハイブリッドアクセスモード設定

次に、AWS Lake Formationハイブリッドアクセスモードに設定します。作業としては以下になります。

  • Glue DB、tableを作り直します。
  • Datalake locationsでPermission mode Lake Formationだったものを削除し、Hybrid access modeに作り直します。

Screenshot 2025-02-05 at 7.43.41

  • Hybrid access modeにLake Formationで制限したいIAM Role hr-data-access-with-lakeformationを登録します。
    Screenshot 2025-02-05 at 7.49.03

ハイブリッドアクセスモード前に作成されたリソースは、Data PermissionsでPrincipal IAMAllowedPrincipalsに対し、All権限が付与されています。
つまり先ほどの表でいうハイブリッドアクセスモードかつGlue許可 (Data Permissions)の状態です。

No.7,9,11検証

  • No.7 (Admin Role)
    Glue、S3への直接的な権限があるため、アクセスできています。
    Screenshot 2025-02-05 at 7.54.23

  • No.9 (直接アクセス権限あり Role)
    Glue、S3への直接的な権限があるため、アクセスできています。
    Screenshot 2025-02-05 at 7.54.53

  • No.11 (直接アクセス権限なし Lake Formation権限あり Role)
    Glue databaseへのアクセスがLake Formationで制限されているため、アクセスに失敗します。
    Screenshot 2025-02-05 at 8.09.02

Data PermissionsでIAM Role hr-data-access-with-lakeformationに対して、tableへのselect権限を付与します。
Screenshot 2025-02-05 at 8.10.02
再度アクセスしたところ、成功しました。
Screenshot 2025-02-05 at 8.11.18

No.8,10,12検証

先ほどの表で言うハイブリッドアクセスモードかつGlue許可 (Data Permissions)×の状態に設定するために、Data permissionsで以下をrevokeします。

  • IAMAllowedPrincipalscm_kasama_hr_employeeに対する全ての権限
  • Admin Roleのdatabase,table,columnに対する全ての権限
  • hr-data-access-with-lakeformationのtableに対する全ての権限

それでは確認していきます。

  • No.8 (Admin Role)
    Glueへの権限が無く失敗します。
    Screenshot 2025-02-05 at 8.34.10

  • No.10 (直接アクセス権限あり Role)
    Glueへの権限が無く失敗します。
    Screenshot 2025-02-05 at 8.34.44

  • No.12 (直接アクセス権限なし Lake Formation権限あり Role)

Glueへの権限が無く失敗します。
Screenshot 2025-02-05 at 8.35.04

最後に

試していても、まだまだ理解が追いついていない点もあるので、引き続き検証したいと思います。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.