イベント駆動型の AWS Glue クローラー:SQS ベースのトリガーを設定する
S3 イベント通知と SQS を使い、バケット全体を繰り返しスキャンせずに AWS Glue クローラーを差分実行します。
AWS Glue クローラーは、S3 イベント通知 を使って、新規または変更されたオブジェクトだけを処理できます。実行のたびにバケット全体をスキャンする必要がないため、クロール時間とコストを抑えられます。

構築
以下の CloudFormation テンプレートで、キュー、バケット、クローラーを構築します。
AWSTemplateFormatVersion: '2010-09-09'Description: Glue crawler test
Resources: SqsQueue: Type: AWS::SQS::Queue Properties: SqsManagedSseEnabled: true QueueName: glue-crawler-test-queue
SqsQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: Queues: - !Ref SqsQueue PolicyDocument: Version: '2008-10-17' Id: __default_policy_ID Statement: - Effect: Allow Principal: AWS: - !Sub arn:aws:iam::${AWS::AccountId}:root - !GetAtt IAMRoleGlueCrawler.Arn Action: sqs:* Resource: !GetAtt SqsQueue.Arn - Effect: Allow Principal: Service: s3.amazonaws.com Action: sqs:* Resource: !GetAtt SqsQueue.Arn
S3Bucket: Type: AWS::S3::Bucket DependsOn: SqsQueuePolicy Properties: BucketName: !Sub glue-crawler-test-${AWS::AccountId}-${AWS::Region} BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 NotificationConfiguration: QueueConfigurations: - Event: 's3:ObjectCreated:*' Queue: !GetAtt SqsQueue.Arn PublicAccessBlockConfiguration: BlockPublicAcls: TRUE BlockPublicPolicy: TRUE IgnorePublicAcls: TRUE RestrictPublicBuckets: TRUE
IAMRoleGlueCrawler: Type: AWS::IAM::Role Properties: Path: /service-role/ RoleName: !Sub glue-crawler-test-service-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: glue.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: cw-logs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: "*" - PolicyName: glue PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - glue:CreateTable - glue:GetDatabase - glue:GetTable - glue:UpdateTable Resource: "*" - PolicyName: s3 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:GetObject - s3:ListBucket - s3:PutObject Resource: '*'
GlueDatabase: Type: AWS::Glue::Database Properties: CatalogId: !Ref AWS::AccountId DatabaseInput: Name: glue-crawler-test-db
GlueTable: Type: AWS::Glue::Table Properties: CatalogId: !Ref AWS::AccountId DatabaseName: !Ref GlueDatabase TableInput: Name: glue-crawler-test-table TableType: EXTERNAL_TABLE Parameters: classification: json StorageDescriptor: Location: !Sub 's3://${S3Bucket}/' Compressed: false InputFormat: org.apache.hadoop.mapred.TextInputFormat OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat SerdeInfo: SerializationLibrary: org.openx.data.jsonserde.JsonSerDe
GlueCrawler: Type: AWS::Glue::Crawler Properties: Name: glue-crawler-test Role: !Sub service-role/${IAMRoleGlueCrawler} Targets: CatalogTargets: - DatabaseName: !Ref GlueDatabase Tables: - !Ref GlueTable SchemaChangePolicy: UpdateBehavior: UPDATE_IN_DATABASE DeleteBehavior: LOGスタックをデプロイします。
STACK_NAME=glue-crawler-test
aws cloudformation package \ --template-file template.yaml \ --s3-bucket <YOUR_CFN_BUCKET> \ --s3-prefix "$STACK_NAME/$(date +%Y)/$(date +%m)/$(date +%d)/$(date +%H)/$(date +%M)" \ --output-template-file package.template
aws cloudformation deploy \ --stack-name $STACK_NAME \ --template-file package.template \ --capabilities CAPABILITY_NAMED_IAMGlue クローラーのターゲット設定を更新する
2023 年 1 月時点では、CloudFormation から Glue クローラーの S3 イベント通知を設定できません。クローラーのターゲットを手動で更新します。
https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/947
CloudFormation Support For S3 Event isn’t currently available. S3 Event Crawler’s integration with CloudFormation is in scope and in the works. We plan on releasing this coverage to Cloudformation some later this year. Thank you for patience.
S3 ターゲットを選択し、Edit をクリックします。

Subsequent crawler runs セクションで Crawl based on events を選択します。

テスト
バージョン 1 のアップロード
サンプルの JSON ファイルをアップロードし、S3 イベント通知を発生させます。
echo '{"message": "Hello World"}' > sample1.jsonaws s3 cp sample1.json s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/Glue クローラーを起動します。
aws glue start-crawler --name glue-crawler-testステータスが STOPPING になるまで監視します。
$ aws glue get-crawler --name glue-crawler-test | jq -r '.Crawler.State'STOPPING更新された Glue テーブルのスキーマを確認します。
aws glue get-table \ --database-name glue-crawler-test-db \ --name glue-crawler-test-table \| jq '.Table.StorageDescriptor.Columns'期待される出力。
[ { "Name": "message", "Type": "string" }]バージョン 2 のアップロード
新しいバージョンの JSON ファイルで同じ手順を繰り返します。
echo '{"message": "Hello World", "statusCode": 200}' > sample2.jsonaws s3 cp sample2.json s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/Glue クローラーを起動します。
aws glue start-crawler --name glue-crawler-testステータスが STOPPING になるまで監視します。
$ aws glue get-crawler --name glue-crawler-test | jq -r '.Crawler.State'STOPPING更新された Glue テーブルのスキーマを確認します。
aws glue get-table \ --database-name glue-crawler-test-db \ --name glue-crawler-test-table \| jq '.Table.StorageDescriptor.Columns'期待される出力。
[ { "Name": "message", "Type": "string" }, { "Name": "statuscode", "Type": "int" }]SQS メッセージ数の確認
SQS キューにメッセージが残っていないことを確認します。
queue_url=$(aws sqs get-queue-url --queue-name glue-crawler-test-queue | jq -r '.QueueUrl')aws sqs get-queue-attributes \ --queue-url $queue_url \ --attribute-names ApproximateNumberOfMessages{ "Attributes": { "ApproximateNumberOfMessages": "0" }}クリーンアップ
この例でプロビジョニングしたリソースを以下のコマンドで削除します。
aws s3 rm s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/ --recursiveaws cloudformation delete-stack --stack-name $STACK_NAMEまとめ
S3 イベント通知を SQS 経由で Glue クローラーへ渡すと、連続してアップロードしたファイルからテーブルスキーマを段階的に更新できます。SQS キューが空になったことで、クローラーが通知を処理したことも確認できます。
イベントベースのクロールでは、クローラーは通知で参照されたオブジェクトだけを処理し、バケット全体を再スキャンしません。データセットが増えても、実行時間とコストを抑えられます。
2023 年 1 月時点では、Subsequent crawler runs を Crawl based on events に切り替える操作にコンソールが必要です。CloudFormation で構成を一元管理したい場合は、リンク先の GitHub issue を確認してください。
Related posts
Cognito User Pools と OIDC で Slack サインインを実装する
Cognito user pool を OIDC 経由で Slack と連携させ、"Sign in with Slack" を Amplify で Next.js アプリケーションに組み込みます。
Lambda Web Adapter で FastAPI を AWS Lambda にデプロイする
FastAPI で書いた API バックエンドをコンテナ化し、Lambda Web Adapter と AWS CDK を使って単一の Lambda 関数へデプロイします。
API Gateway WebSocket:モック統合の実装
バックエンドの Lambda を使わず、モック統合のみで API Gateway WebSocket API を構築し、あらかじめ用意したレスポンスを返します。
CloudFront 署名付き URL 経由で S3 にアップロードする
CloudFront の署名付き URL を使い、独自ドメイン経由で S3 にアップロードする方法を紹介します。S3 の署名付き URL を直接使えない場合に有用です。
AWS EventBridge Scheduler:スケジュールに沿って EC2 を起動・停止する
Lambda を介さず、EventBridge Scheduler から EC2 API を直接呼び出し、cron スケジュールに従って EC2 インスタンスを起動・停止します。
