AWS SAMを利用したAWS Lambdaのインフラ環境構築

スポンサーリンク

今回、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だけでなく、様々なサーバレスアプリケーションを管理できるので、詳しく知りたい方は 公式ドキュメントを確認してみてください。