概要
- S3にたくさん投入したデータをAthenaでサクッと分析・集計できるようにする際、Glue Crawlerが非常に便利。
- CDKで構築した例はまだあまりなかったので記事化。
S3の設定について
- 先日の記事で考察したが、S3はいまのところ手動設定したものを利用しても良いように思う。
Glueの設定について
- 上記の理由より、S3はすでにあるものを利用する形にする。
- Roleについては、公式(日本語が怪しいですが)の通り、マネージドポリシーの
AWSGlueServiceRole
を付与し、さらにインラインポリシーで対象のS3パスへのGetObject・PutObjectを許可
するようにします。 -
CDKのConstructは「High Level Construct」「Low Level Construct」「Patterns」の3種がありますが、Glue Crawlerについては2020/11/26現在、まだ 「Low Level」=
Cfn...
系のものしか無い(公式doc)ので、CfnCrawler
を使います。 -
Glue Crawlerが意図しない複数のテーブルを作ってしまうことがあるので、今回はコンソール画面で設定できる「S3パスごとに単一のスキーマを作成する」ようにします。
- これの実現方法を探すのに苦労しました。参考のStack Overflow。
'{"Version": 1.0, "Grouping": {"TableGroupingPolicy": "CombineCompatibleSchemas"}}'
- GlueはVersion 2.0もありますが、指定すると未対応らしく "Version 2.0 is not supported." というエラーが出ます。
- 分類子(Classifier)は
CfnClassifier
で「名前(name
)を指定して生成」し、CfnCrawler
のprops
内、classifiers
にその名前を与えて使います。今回は割愛。
- これの実現方法を探すのに苦労しました。参考のStack Overflow。
ソースコード例
たとえばこんな感じ。
import * as cdk from '@aws-cdk/core';
import * as iam from '@aws-cdk/aws-iam';
import * as glue from '@aws-cdk/aws-glue';
import * as s3 from '@aws-cdk/aws-s3';
export class MyStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const myBucketName = 'my-bucket';
const myCrawlerName = 'myCrawler';
const myCrawlerRoleName = 'myCrawlerRole';
const myAthenaDBName = 'my_db';
const myBucket = s3.Bucket.fromBucketName(this, myBucketName, myBucketName);
const myCrawlerRole = new iam.Role(this, myCrawlerRoleName, {
assumedBy: new iam.ServicePrincipal('glue.amazonaws.com')
});
myCrawlerRole.addManagedPolicy(
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole'));
myCrawlerRole.addToPolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
resources: [`${myBucket.bucketArn}/path-to-object-parent/*`],
actions: ["s3:GetObject", "s3:PutObject"]
})
);
const myCrawler = new glue.CfnCrawler(this, myCrawlerName, {
role: myCrawlerRole.roleArn,
databaseName: myAthenaDBName,
targets: {
s3Targets: [{ path: `${myBucket.s3UrlForObject()}/path-to-object-parent/` }]
},
configuration: '{"Version": 1.0, "Grouping": {"TableGroupingPolicy": "CombineCompatibleSchemas"}}'
});
}
}
まだ良くわからないこと
わかる方いらっしゃいましたら教えてほしいです。
- Constructの「id」の活用方法。今のところ適当。
- S3もCDKで管理できたら良いけど、CDK(というかIaC?)の利点を活かせるやりかたは今のところ不明。
- TypeScriptはまだ1週間ほどしか触っていないので、いろいろ不安。