ここが辛いよLambda


はじめに

久しぶりにAWS Lambdaをしっかりめに使う機会が業務でありました。Lambdaは基本的には便利なサービスなのですが、使い込むうちに色々と辛いところも見えてきました。具体的に何が辛かったのかと、どう対処すればよかったのかを振り返りながら記録していきます。

250MBクォータ

Lambda関数には容量の上限が設けられています。関数本体とLambda Layerとで合計250MBまでに収める必要があります。超過した際はUnzipped size must be smaller than 262144000 bytesというエラーが発生します。

Claudeに聞いたところ、おおよそPythonで500万〜800万行くらい書けば250MBに相当するようです。小規模〜中規模の実装であれば250MBで十分足りると思いますが、規模の大きいアプリケーションだと怪しくなってきます。実際、「Lambda 250MB」で検索してみると困ってる方が多くいました。

google

例えば、依存ライブラリを複数利用する場合はライブラリのサイズも含まれるため、割とすぐクォータに引っかかります。(自分のケースでは、Oracle DB向けのコネクションライブラリを利用した際に300MBくらいまで膨れ上がりました)

辛かったこと

250MBクォータに引っかかった場合の対応は2つあって、①250MB未満になるようにリソースを減らす②ECRにリソースをPUSHする の二択になります。

一つ目は単純で、250MB未満になるまでリソースを削っていくことになります。これは合計容量が255MBなどのようなちょっとだけ超過した時には有効な手段で、不要なライブラリの削除やソースコードのリファクタリングなどで解消する可能性が高いです。ただし、300MBなどのように大幅に超過した場合、多少削るくらいではあまり意味を成しません。

二つ目は、Lambda関数をコンテナイメージとしてビルドし、そのイメージをECRにPUSHします。従来のLambda関数はソースコードをzipに圧縮してAWS上にデプロイするのがデフォルトの方式ですが、コンテナイメージ方式ではzipは利用しません。関数実行時はECR上のイメージを参照して実行します。

このようにコンテナイメージとしてLambdaをデプロイする機能は2020年12月にリリースされた機能のようです。

コンテナイメージとしてデプロイする場合、イメージのサイズは最大10GBまで許容されています。 従来のzipスタイルのLambdaの40倍です。最強です。

ただし、zipスタイルのLambdaをコンテナイメージ方式に途中から切り替える場合は少し大変なので注意です。
例えばSAMやCDKを利用している場合はアーキテクチャの設定ファイルを大幅に書き直す必要があります。まあLLMにやらせればそんなに時間はかかりませんがソースコード差分は結構出るので、コードレビューの際はレビュアーにしっかりと理由を説明する必要があります。また、デプロイの際はECRに関するIAMポリシーが色々と必要になるので、権限の弱いアカウントでは追加でポリシーの申請をすることになります。

どうすればよかったか

構築前に250MBクォータに抵触しないかどうかを見積りましょう。
zipスタイル or コンテナイメージスタイルのどちらを採用すべきかを事前に確定させておくことが肝要です。後から方式を変えるのは大変です。

SAM or CDKの選択

Lambdaのデプロイにはいくつか方法があります。

  • AWS SAM CLI・・・CloudFormationをサーバーレスアプリケーション向けにカスタマイズしたツール。sam build, sam deployなどのコマンドを実行するとcfnスタックが作成されていい感じにLambdaのデプロイを実施する。
  • AWS CDK/terraform・・・王道のIaC.
  • 手動でリリース・・・zipを手動でアップロード/ECRに手動でイメージをpush。

手動リリースは選択外として、自分の中ではSAM or CDK or terraformでした。色々考えたのですが、Lambda関数一個をデプロイするためだけにCDK/terraformを使うのは大掛かりかなあと思って、SAMでリリースする方法を採用しました。

自分は今回初めてSAMを使いましたが、中々便利なツールでした。

基本的には、sam buildでビルドしたものをsam deployでデプロイする、というシンプルな流れです。(色々オプションもあります)SAM向けの設定ファイルとしてtemplate.yaml, samconfig.tomlという独自のファイルがありますが、そこまで取っ付きづらいものではありません。

辛かったこと

SAM自体はとてもいいツールだったのですが、SAMの認知度の低さに少し苦労しました。少なくとも私の所属するチームでは「聞いたことあるけどよく知らない」という方が多かったです。認知度が低いと、PJを他者に引き継ぐ時の説明コストが増えます。また、私の所属するチームではアプリとインフラでチームが分かれており私はアプリ側のチームにいます。インフラ周りの本番作業はインフラ側のチームに依頼することが多く、その際もSAMの説明コストが少し高かったです。(先方がSAMを全く知らないというわけではないがSAM CLIの細かなオプションなどは知られていなかった)

どうすればよかったか

チーム内で既に採用されているIaCに寄せる方がチームコミュニケーションは楽になるなと実感しました。今回私はSAMを使いましたが、チーム内ではterraformが使われている箇所がいくつかあったので、terraformにしておけばよかったなあと後から後悔しました。

まとめ

  • Lambdaの250MBクォータには気をつけろ
  • デプロイ手法はチーム内の他メンバーのことも考えて選定しよう。あまり認知されていないものは説明コストが上がる。