patorashのブログ

方向性はまだない

Lambda Web Adapterのコンテナでタスクを実行する

前回、Lambda Web Adapterを使ってSinatraアプリをAWS Lambdaで動かす話をしました。

patorash.hatenablog.com

今回は、Lambda Web Adapterを使っているコンテナでサーバーレスでタスクを実行する方法についてです。

タスクはrake taskを実行すればいいんでしょ?

はい。私も最初はそう思っておりました…。そのため、新たにLambdaを作って、同じDocker Imageを使うようにして、DockerのCMDを上書きしてrake taskを実行するようにしてみました。そしてLambda関数の詳細画面のテストタブから、テストを実施。

すると、期待通りのrake taskは実行されているんだけれど、テストが必ず失敗しました。原因は、『Lambda Web AdapterがHTTPのリクエストを期待して待っている間にrake taskが終了してexit 0が行われるため、Lambda Web Adapterからしたら勝手に終了させられた!と認識してしまうため』でした(長い)。

ということで、Lambda Web Adapterを含んでいるDockerコンテナでは、rake taskは使えません!!

Non-HTTP Event Triggers の存在を知る

まぁ、ちゃんと本家のREADMEを読めって話ですよ…。

github.com

Non-HTTP Event Triggersは、他のAWSのサービスからLambdaを呼び出すときに使うトリガーということですが、その受付口として、デフォルトで POST /events のパスにアクセスすればいいとあります。

ということで、Sinatraで早速、POST /eventsで処理を受け付けるようにして、rake taskで行っていた処理を移植しました。

前回の実装でAPI Gatewayから全てのリクエストはLambdaに転送するようにしてあるので、特に修正は不要。rake task用に作っていたLambda関数は削除しました。Docker Imageを更新してLambdaにデプロイし直した後、テストタブからLambda関数に対して POST /events に向けてリクエストを実施。普通に処理されました🎉

EventBridge Schedulerから呼び出す

決まった時間帯に処理を行いたかったため、EventBridge Schedulerを定義してみました。cronのルールで対象のLambda関数を呼び出すようにして、JSONペイロードPOST /events を表すものを記載してみました。パラメータはbodyに定義するので、適宜変えてください。

{
  "version": "2.0",
  "routeKey": "POST /events",
  "rawPath": "/events",
  "rawQueryString": "",
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "requestContext": {
    "http": {
      "method": "POST",
      "path": "/events"
    }
  },
  "body": "name=taro&age=35",
  "isBase64Encoded": false
}

また、決まった時間に処理を行うことよりも確実に処理を行える可能性を高めるほうを重視して、フレックスタイムウィンドウを15分に設定しました。

翌日、動作したか確認したところ、問題なく動作してたのでOK!!いやー、どんどん『サーバーレスチョットデキル』ようになってきています!✌️

サーバレスに移行後のコストメリットはあるのか?

まだ移行はしてないんですが、Railsを動かしているVPSの利用料が月額4,000円近くなのに対し、API Gateway + Lambda + DynamoDBに移行したら恐らく月額500~1,000円程度になるのでは?と思います。小さなコストカットではありますが、似たようなRailsアプリがちょこちょこあるので、どんどんこの構成に移植すれば、塵も積もればで年間で十数万のコスト削減になるかなと考えてます。あと金銭的なメリットもさることながら、サーバーレスであることが嬉しい。