今回、AWS LambdaとEventBridgeを利用した定期実行、AWS LambdaとSQSを利用した分散処理の仕組みを作成したので、どのようにインフラ環境を構築したかについて触れていきたいと思います。
これまで apex(メンテナンス終了)やserverlessを利用してきましたが、今回はAWSが公式に公開しているSAMを利用する事にしました。
システム構成
システム構成図
システムの目的は定期的に特定のWeb Serverからデータを取得し、特定のS3 Bucketにデータを保存します。
URL一覧は数万件のURLが含まれているため、URL毎に分散処理を行っています。
ディレクトリ構成
web_crawler/
├ src/
│ └ app.py
└ template.yaml
※ app.py
の内容に関しては今回は説明しません。
SAMテンプレート
- template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Web crawler
Globals:
Function:
Timeout: 300
Resources:
WebCrawlerTopPageFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.toppage
Runtime: python3.9
Policies:
- SQSSendMessagePolicy:
QueueName:
!GetAtt WebPagesSqsQueue.QueueName
Events:
MySchedule:
Type: Schedule
Properties:
Schedule: 'cron(0 0 * * ? *)'
Name: MySchedule
Description: My Schedule
Enabled: true
Input: 'JSON形式でLambdaに渡すイベント'
WebCrawlerInPageFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.in_page
Runtime: python3.9
Policies:
- S3FullAccessPolicy:
BucketName:
"{保存先のBucket名}"
Events:
SQSEvent:
Type: SQS
Properties:
Queue: !GetAtt WebPagesSqsQueue.Arn
WebPagesSqsQueue:
Type: AWS::SQS::Queue
Properties:
VisibilityTimeout: 300
FifoQueue: true
Resources
SAMで作成するAWSのリソース(AWS LambdaやAWS SQSなど)を定義します。
WebCrawlerTopPageFunction
EventBridgeのスケジュールをトリガーに、WebServerからURL一覧を取得しSQSにメッセージを送信するAWS Lambdaを定義します。
- Type: AWS::Serverless::Function
- リソースタイプとして、AWS Lambdaを指定しています。
Policies
AWS Lambdaに対する権限を定義します。
- SQSSendMessagePolicy
- AWS Lambdaに対し、SQSへメッセージを送る権限を設定しています。
Events
AWS Lambdaのトリガー条件を定義します。
- Type: Schedule
- 起動条件として
EventBridge
のスケジュールを指定しています。
- 起動条件として
WebCrawlerInPageFunction
SQSのメッセージをトリガーに、WebServerからデータを取得しS3 Bucketに書き出すAWS Lambdaを定義します。
- Type: AWS::Serverless::Function
- リソースタイプとして、AWS Lambdaを指定しています。
Policies
AWS Lambdaに対する権限を定義します。
- S3FullAccessPolicy
- AWS Lambdaに対し、S3へのアクセス権限を設定しています。
Events
AWS Lambdaのトリガー条件を定義します。
- Type: SQS
- 起動条件として、SQSのイベントを指定しています。
WebPagesSqsQueue
WebCrawlerTopPageFunction から WebCrawlerInPageFunction に連携するためのAWS SQSを定義します。
- Type: AWS::SQS::Queue
- リソースタイプとして、AWS SQSを指定しています。
Properties
- VisibilityTimeout: 300
- メッセージを表示してから再度可視化されるための可視性タイムアウトを設定します。
- AWS Lambdaのタイムアウトよりも長く設定する必要があります。
- FifoQueue: true
- 標準キューからFIFOキューに変更しています。
- 重複メッセージの排除を目的に、FIFOキューを指定しています。
インフラのデプロイ
インフラのデプロイはSAMコマンドを利用して行います。
コマンドのインストールに関してはドキュメントを確認ください。
ビルド
SAMはCloudFormationの定義ファイルを利用しているため、SAMのテンプレートファイルからビルドを行う必要があります。
sam build
デプロイ
ビルドが完了したら、デプロイを行います。
最初はデプロイのための設定を行う必要があるため、 --guided
を指定します。
一度設定すると、 samconfig.toml
が作成され、プロンプトによる設定は不要になります。
# 初回時
sam deploy --guided
# samconfig.tomlが作成されて以降
sam deploy
終わりに
今回は参考としてAWS Lambda、AWS SQS、AWS EventBridge、S3の環境を構築できるSAMテンプレートを書いてみました。
SAMはAWS Lambdaだけでなく、様々なサーバレスアプリケーションを管理できるので、詳しく知りたい方は 公式ドキュメントを確認してみてください。