4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Serverless Frameworkで管理しているLambdaのランタイムが(一部)更新されない問題

はじめに

AWS Startup Community主催のイベント「AWS 本当にあった怖い話トーク」に登壇しました。
この記事は、その登壇内容をまとめたものです。

問題

Serverless Framework v3を利用して、AWS LambdaのランタイムをNode.js 18からNode.js 20へ一括更新しようとしました。
しかし、serverless.ymlprovider.runtimenodejs20.x に変更してデプロイしても、一部のLambdaランタイムが更新されないという問題が発生しました。

補足: Serverless Frameworkとは?

Serverless Frameworkは、AWS Lambdaをはじめとするサーバーレスなアプリケーションを簡単に構築、デプロイ、管理するためのオープンソースのツールです。

serverless.yml または serverless.ts という単一の設定ファイルにインフラの構成を記述するだけで、フレームワークが裏側でCloudFormationのテンプレートを自動生成し、リソースのプロビジョニングやデプロイを行ってくれます。

Infrastructure as Code (IaC)を実現するツールの一つであり、手動でのインフラ管理の手間を大幅に削減し、開発者がアプリケーションのコードに集中できる環境を提供します。

背景:なぜランタイムが更新されないLambdaが存在したのか

私がこの問題に直面したのは、開発チームで管理している既存のS3バケットにファイルがアップロードされたことをトリガーにして、特定の処理を行うLambda関数を実装する必要があったからです。

Serverless Frameworkでは、serverless.ymlでS3イベントを定義することで、S3とLambdaの連携を簡単に設定できます。
しかし、S3バケットがServerless Frameworkの管理外にあり、すでに存在している場合は、eventsの設定に existing: true というフラグを追加する必要があります。
(参考: https://www.serverless.com/framework/docs/providers/aws/events/s3#using-existing-buckets)

# serverless.yml
functions:
  hello:
    handler: handler.hello
    events:
      - s3:
          bucket: your-existing-bucket # 既存のバケット名を指定
          event: s3:PutObject:*
          existing: true # このフラグが重要

このexisting: trueこそが、今回の問題の引き金でした。

このフラグを設定すると、Serverless Frameworkはカスタムリソースと呼ばれる特別なLambda関数を裏側で自動的に生成します。このカスタムリソースは、既存のS3バケットに対して、Lambdaを呼び出すためのイベント通知設定を追加・管理する役割を担っています。

原因

調査を進めた結果、Serverless FrameworkのGitHubリポジトリに同様のissueが報告されていました。

また、このカスタムリソースとして自動生成されるLambdaのランタイムが、Serverless Frameworkのコード内で固定(ハードコード)されていたことも判明しました。

そのため、serverless.ymlprovider.runtimenodejs20.xを指定しても、他関数のランタイムは更新される一方で、フレームワークが自動生成したカスタムリソースのLambdaは古いランタイムのまま取り残されてしまったのです。

これが、一部のLambdaランタイムが更新されなかった問題の真相です。

解決策

issueにあったコメントを参考にすると、serverless.ymlresources セクションで extensions を使い、影響を受けるカスタムリソースのランタイムを明示的に上書きすることで、この問題を解決できます。

# serverless.yml
service: sls-runtime-test
frameworkVersion: "3"

provider:
  name: aws
  runtime: nodejs20.x

functions:
  hello:
    handler: handler.hello
    events:
      - s3:
          bucket: some-bucket
          event: s3:PutObject:*
          existing: true

resources:
  extensions:
    CustomDashresourceDashexistingDashs3LambdaFunction:
      Properties:
        Runtime: nodejs20.x # この指定によりカスタムリソースのランタイムが更新

この設定を適用して再度 serverless package を実行すると、生成されたCloudFormationテンプレートにおいて、カスタムリソース用Lambdaのランタイムが nodejs20.x に正しく更新されていることが確認できます。

この状態で再度sls deployを実行すると、デプロイは成功し、また問題なく該当Lambdaのランタイムも更新されました。

まとめ

Serverless Frameworkは非常に便利なツールですが、内部的な実装によって意図しない挙動が発生することがあります。
問題が発生した場合は、公式ドキュメントやGitHubのissueを調査することが、迅速な解決に繋がります。

今回の経験を通じて、ツールの内部実装を理解することの重要性を改めて認識しました。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?