【AWS】LakeFormationのBlueprintを使ってデータ分析基盤を構築してみた
概要
先日、データ分析基盤を構築することになり、手探りで這いつくばりながら、どうにか構築することができました。長いですが、このとおり進めれば構築できると思います。少しでも参考になれば嬉しいです。
AWSLakeFormationは、データ分析基盤を構築する際の権限管理やデータカタログ作成をサポートしてくれるすごいやつです。
今回は、AWSLakeFormationを利用して、下記を実現します。
- RDSからデータを取得し、Glueがデータカタログを作成。それをもとにAthena実行ユーザーがAthenaでSQLを叩けるようにする。
- 「RDSからデータを取得し、Glueがデータカタログを作成」の部分は、Blueprintを使って定期実行するようにし、最新(1日1回のデータ取得)のRDSのデータカタログを作成するように設定。
今回の完成版構成図です。
登場人物
- 管理者ユーザー(AdministratorAccess権限をもつ)
- DataLake管理者ユーザー
- Athena実行ユーザー(AthenaではSELECT文のみ許容)
手順
データレイクとなるS3バケットを作成
AdministratorAccess権限を持つユーザーでログイン後、バケットを作成
上記のように入力後、バケットを作成をクリック
IAMでDataLake用ユーザー作成
DataLake管理者ユーザー(datalake_admin_user)を設定
ユーザーを作成
IAM > ユーザーからユーザーを追加
↓
グループの作成をクリック
↓
グループ名「dl_admins」とし、グループの作成をクリック
↓
タグは未設定
ユーザーの確認後、ユーザーの作成
dl_adminsグループに権限を付与
↓
以下ポリシーをアタッチ
AmazonAthenaFullAccess
CloudWatchLogsReadOnlyAccess
AWSGlueConsoleFullAccess
AWSLakeFormationCrossAccountManager
AWSLakeFormationDataAdmin
LakeFormationServiceRolePolicy(インラインポリシー)
LakeFormationServiceRolePolicy(インラインポリシー)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:AWSServiceName": "lakeformation.amazonaws.com"
}
}
},
{
"Effect": "Allow",
"Action": [
"iam:PutRolePolicy"
],
"Resource": "arn:aws:iam::<account-id>:role/aws-service-role/lakeformation.amazonaws.com/AWSServiceRoleForLakeFormationDataAccess"
}
]
}
※<account-id>に自身のアカウントIDをいれること
↓
設定後
Athena実行ユーザー(datalake_user)を設定
ユーザーを作成
iAM > ユーザーからユーザーを追加
↓
グループの作成をクリック
↓
グループ名「dl_users」とし、グループの作成をクリック
↓
タグは未設定
ユーザーの確認後、ユーザーの作成
dl_usersグループに権限を付与
↓
以下ポリシーをアタッチ
AmazonS3FullAccess
AmazonAthenaFullAccess
LakeFormationGlueGetPolicy(インラインポリシー)
LakeFormationGlueGetPolicy(インラインポリシー)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lakeformation:GetDataAccess",
"glue:GetTable",
"glue:GetTables",
"glue:SearchTables",
"glue:GetDatabase",
"glue:GetDatabases",
"glue:GetPartitions",
"lakeformation:GetResourceLFTags",
"lakeformation:ListLFTags",
"lakeformation:GetLFTag",
"lakeformation:SearchTablesByLFTags",
"lakeformation:SearchDatabasesByLFTags"
],
"Resource": "*"
}]}
↓
設定後
Crawlerで利用するRoleを作成
テーブル作成をGlueのCrawler経由で行うため、Crawlerで利用するRoleを作成
(AWSGlueServiceRoleDefaultDataLakeDataAccess)
↓
以下ポリシーをアタッチ
- Managed Policy
- AWSGlueServiceRole
- AmazonS3ReadOnlyAccess
↓
ロールの作成をクリック
↓
インラインポリシーの追加
(LakeFormationGetPolicy)
↓
以下を設定
InlinePolicy:Lakeformationの利用権限を追加
lakeformation:GetDataAccess
lakeformation:GetResourceLFTags
lakeformation:ListLFTags
lakeformation:GetLFTag
下記画像のようにサービスはLakeFormationを選択して、アクションを選んでいく
↓
↓
更にインラインポリシーの追加
以下を設定
IAM:PassRole
↓
↓
設定後
LakeFormationの権限設定
Lake Formationの管理者追加
Lake Formation管理者用ユーザ(datalake_admin_user)を管理者に追加する。
AWS Lake Formation > Administrative roles and tasks
↓
Lake Formationで不要な権限解除
Lake Formationでアクセス制御を一元管理するために不要な権限設定を解除します。
IAM access controlのみを利用したDatabase/Tableへのアクセス制御を無効化
AWS Lake Formation > Data catalog settings
下記のチェックを外した状態でsave
- Use only IAM access control for new databases
- Use only IAM access control for new tables in new databases
エラーが出ているが解除できている
IAM権限のみで、Lake FormationのDatabase作成ができる状態を無効化
「Administrative roles and tasks」の「Database creators」から「IAMAllowedPrincipals」を選択してRevoke
↓
Revoke
アクセス制御用のタグ作成
Lake Formation管理者ユーザ(datalake_admin_user)でログイン
LF-Tagsからアクセス制御に利用するタグを追加
DatabaseをCrawlingするためのLF-Tag
Tag Key: maintenance
Tag Values: cralwer,manual
LakeFormation > LF-Tags
Add LF-tag
↓
↓
もう一つLF-tagを設定
ユーザ制御のためにTableに付与するLF-Tag
Tag Key: source
Tag Values: product
アクセス制御用のタグ設定
作成したタグが付与されたリソースをGlue Crawler用のRole「AWSGlueServiceRoleDefaultDataLakeDataAccess」に設定します。「data lake permission」から、LF-tag(maintenance/cralwer)が付与されたDatabase/Tableに対するSuper権限を付与します。
要はAWSGlueServiceRoleDefaultDataLakeDataAccessロールにDBとテーブルのSuper権限を付与する。
横のメニューから「Data Lake Permission」を選ぶ
Grant
↓
↓
ok
Athena実行ユーザ「datalake_user」がTag (source/product)権限によりTable操作ができるように、TABLEに対するSELECT, Describe権限を付与します。
Grant
↓
Grant
↓
設定後
ok
Data Lake Locationの設定
追加
データが保存されているS3 BucketをData Lake locationsに登録します。Data Lake Locationに追加することで、追加されたS3 bucket (path)へのアクセスをLake Formationで管理します。ユーザに登録RoleへのputRolePolicy権限がある場合、登録したS3パスへの接続権限が自動で登録Roleに付与されます。
AWS Lake Formation > Data lake locations
↓
↓
ok
初回登録時は、自動でservice-lined role「AWSServiceRoleForLakeFormationDataAccess」が作成される
Data Locationのアクセス権限追加
Data Lake Locationに設定したS3パス(Data Location)配下のデータをData CatalogのTableに追加するために、Data LocationとRoleを紐づけます。
AWS Lake Formation > Data locations
Grant
↓
Grant
↓
設定後
ok
Databaseの追加
Data Catalog>Databasesの[Create database]ボタンから、データベ ースを作成します。
Create database
↓
Create database
↓
Lake FormationでDatabaseを作成した場合、裏でGlue Databaseが作成されます。そのため、Glueのコンソールから同じ名称のデータベースが確認できます。
DatabaseにLF-Tagsを追加
以下のLF-TagをDatabaseに追加し、対象のTagを持つuser/roleから利用できるようにします。
DatabaseにLF-Tagsを設定することで、このLF-Tagsが付与されたAWSGlueServiceRoleDefaultDataLakeDataAccessから利用できるようにする
DatabaseにLF-Tagを設定した場合、Databaseに紐づくTableにLF-Tagが継承されます
Key : maintenance
Value: crawler
Edit LF-tags
↓
Assign new LF-Tag
↓
↓
設定後
ブループリントで自動化する
GlueからDBに接続するための設定
Glue > 接続
接続の追加
↓
ご自身のDB情報に合わせて入力してください
↓
ご自身のDB情報に合わせて入力してください
↓
完了
↓
接続のテスト
↓
接続のテストをクリック
↓
エラー発生
DBセキュリティグループ修正
AWS Glue コンポーネントで通信を可能にするには、Amazon RDS などのデータストアへのアクセスを設定する必要があります。
AWS Glue とRDSで通信できるようにするには、すべての TCP ポートに対して自己参照のインバウンドルールを持つセキュリティグループを指定します。
自己参照ルールを作成することで、ソースを VPC 内の同じセキュリティグループに制限することができ、ネットワーク全体には公開されません。
手順
RDSへいってRDSにアタッチされているSGを確認する
この場合は、sg-040f846c94bc055f1を変更する
セキュリティグループのインバウンドのルールを編集をクリック
↓
下記に変更
[Type (タイプ)] All TCP
、
[Protocol (プロトコル)] は TCP
、
[Port Range (ポート範囲)] にはすべてのポートが含まれ、
[Source (ソース)] は [Group ID (グループ ID)] と同じセキュリティグループ名である(自分のsgに変更する)
というルールを追加または確認します。
これで、ソースを VPC 内の同じセキュリティグループに制限することができ、ネットワーク全体には公開されず安全
↓
接続のテストを再実行
↓
別のエラー
「接続」を作成したVPCにS3のVPCエンドポイントを作成する
手順
VPC > エンドポイント
エンドポイントをクリック
↓
エンドポイントを作成
↓
※[サービス名] で com.amazonaws.us-east-1.s3 を選択します。[タイプ] 列にゲートウェイと表示されていることを確認してください。注:us-east-1 は必ず、お好みの AWS リージョンに置き換えてください。
※[VPC]では、エンドポイントを作成する VPC を選択します。
※[ルートテーブルの設定] では、S3 VPC エンドポイントへのルートが自動的に追加されます。
※[ポリシー] では、デフォルトオプション [フルアクセス] のままにできます。
↓
再接続テスト
↓
できた
ブループリントを使用してワークフローを作成する
Use bluepoint
↓
Create
※毎日9時45分(UTC)に実行するように設定
↓
ワークフローの実行
start
ステータスは、[RUNNING] (実行中) から、[Discovering] (検出中)、[Importing] (インポート中)、[COMPLETED] (完了) と推移します。
↓
30分くらいかかった
DataLake(S3)にデータが取り込まれている
作成されたDBにLF-tagsを付与
Athena実行ユーザー(datalake_user)に付与しているsource: productを付与する
Athena実行
Athenaのクエリ結果がオブジェクトとして保存される場所を設定
S3バケットを作成
保存先の設定
Athena実行ユーザー(datalake_user)でログイン後、Athenaへ移動
設定を表示
↓
管理
↓
選択
↓
保存
クエリを実行
テーブル名の右の三点リーダをクリックし、「テーブルをプレビュー」を実行
例)
テーブルのレコード数
SELECT COUNT(*) FROM "kthr01"."workflow_kthr01_products";
テーブルの最新の10レコード
SELECT
*
FROM
"kthr01"."workflow_kthr01_products"
ORDER BY
created_at DESC
limit 10
おわり
手探りながら這いつくばりながら、どうにか構築できました。
もっとよい設定や、よりベターなプラクティスがあればご教示いただけると幸いでございます。
参考記事
たいへん参考になりました。
Discussion