[レポート] AWS Lambda の Powertools についてエキスパートレベルの知識を学ぶ「Gain expert-level knowledge about Powertools for AWS Lambda」 #AWSreinvent #OPN402
リテールアプリ共創部の中野です。
re:Invent 2024 で開催された「Gain expert-level knowledge about Powertools for AWS Lambda」というセッションについてレポートします。
セッション概要
概要(re:Invent 2024 イベントサイトより抜粋)
Did you learn serverless best practices but are unsure about implementation? Have you used Powertools for AWS Lambda but felt you barely scratched the surface? This session dives deep into observability practices, resilient data pipelines with AWS Batch, safe retries with idempotency, mono- and multi-function APIs, and more. Learn about each practice in depth, achieve expert-level knowledge, and hear from maintainers about what’s next.
日本語概要(Deepl 翻訳)
サーバーレスのベストプラクティスを学んだが、実装についてはまだわからないことがあります。
AWS Lambda の Powertools は使ったことがあるが、まだ表面的なことしか理解していないと感じています。
このセッションでは、監視の実践、AWS Batch による弾力性のあるデータパイプライン、べき等性による安全な再試行、単機能および多機能 API などについて詳しく説明します。
各実践について深く学び、エキスパートレベルの知識を習得し、メンテナから次に来るものについて話を聞きます。
セッション動画
タイトル
OPN402 | Gain expert-level knowledge about Powertools for AWS Lambda
スピーカー
Andrea Amorosi
LEVEL
400 – Expert
セッションレポート
アジェンダ
アジェンダは以下の通りです。
-
- Powertools for AWS Lambda
-
- Structured logging
-
- Event handler
-
- Idempotency
-
- Batch processing
-
- Roadmap and wrap up
本ブログでは個人的に印象に残ったポイントのみピックアップします。
Powertools for AWS Lambda とは
Powertools for AWS Lambda は、2020 年に発表された Lambda 用のツールキットです。
Lambda 関数の開発を効率化し、ベストプラクティスに沿って簡単に実装できるようにするものです。
これらの機能により、開発者はビジネスロジックに集中でき、ボイラープレートコードを削減できます。
Powertools for AWS Lambda は、Python、Java、TypeScript/JavaScript など、複数のプログラミング言語をサポートしているようです。
構造化されたログについて
Lambda のログを保存する一般的なログ形式は以下の 4 つがあります。
- Raw
- Semi-structured
- Canonical
- Structured
Raw(PowerTools なし)
- Python や Node.js などのロギングライブラリを利用(Node.js の console.log など)
- 出力のときにログレベルを指定して文字列が発行される
- CloudWatch Logs に出力された場合は、ログ形式はリクエスト ID、ログレベル、ログペイロードが出力
- 開発環境でのデバッグでは問題ないが、実本番環境だとたくさんのメタデータが含まれるログなので解析が大変になる
検証段階ではライトに利用できるが、本番運用時にはオブジェクトやディクショナリにして読みやすくしたくなる
Semi-structured(PowerTools なし)
- Semi-structured でも、ログ形式はリクエスト ID、ログレベル、ログペイロードが含まれる
- メッセージ部分がオブジェクトやディクショナリ形式になることで Raw よりは読みやすくなる
Canonical(PowerTools なし)
- Canonical ログ(標準ログ)をチームで標準的に作成して利用
- フォーマットを自分で作成して出力形式を揃える
Structured(PowerTools なし)
- CloudWatch Logs でログ保存をしている場合は、構造化されたログ形式(Structured)を利用
- 基本的には JSON 形式で保存
- CloudWatch Logs には構造化されたログはインデックスされる
- CloudWatch Logs Insights を利用することで、クエリを書いて特定のログを検索しやすい
PowerTools なしで構造化ログを出力する場合は、プロダクションコード側が複雑になってきています。
私が実装するときもこの形式になることが多い印象でした。
Structured(PowerTools あり)
- Structured(PowerTools なし)と比較して、文字列、タイムスタンプ、リクエスト ID が存在しない
- すべて JSON 形式になる
- プロダクションコードもシンプルになる
- CloudWatch やサードパーティのログシステムでもログ解析しやすい形式をサポート
Python の PowerTools の場合は、inject_lambda_context のデコレータを付与するとコンテキスト情報をログに付与できます。
また、セッションでは触れられていませんでしたが、TypeScript ベースの Lambda の場合は、injectLambdaContext で同じことができるようです。
さらに、Correlation ID を設定することで、API Gateway から呼び出された Lambda のリクエストログを JMESPath として引数で渡すとログとして保存もできます。
API と Lambda のリクエスト時のリクエストの一対一の対応がわかりやすいため、どの API でエラーが発生してどの Lambda で問題が起こったのか本番環境のデバックでの利用で有効活用できそうです。
BYO(Bring Your Own Format)を利用するとカスタムのログフォーマッターを生成できます。
例えば、標準化の文脈で出力しておく必要のあるフィールドを事前に定義したりする場合に有用そうです。
Wide Logs という概念がでてきました。
私が運用している環境では、Lambdalith で実装している場合が多く、かなりの量のログが CloudWatch Logs に書き込まれます。
この書き込みによって PutEvents の料金がかなり高額になってしまったり、ログ自体を見つけることが大変になる印象でした。
こういったことを解決するために、Lambda の実行ごとに 1 つのログを発行したり、呼び出しごとに 1 つまたは 2 つのログを発行したりすることを可能になります。
運用が進むにつれ、Lambda から CloudWatch Logs への PutEvents で料金が高額になっており、コスト最適化の 1 つの手段として Wide Logs をつかうのは有用だなと思いました。
Event Handler について
Lambda を使ったことがある人ならわかるとおもいますが、Lambda には Event Handler を定義する必要があります。
最初に関数が呼び出されると、Lambda はこのハンドラーメソッドを実行します。
このハンドラーメソッドが呼び出される都合上、API として受け付けたリクエストのルーティングやバリデーションなどを実行する責務があります。
何も考えず、自分の手で書いていくと以下のようなコードになりますが、エッジケースや実装漏れなど気づきにくいコードになります。
例えば、Lambdalith で一つの Lambda で複数の API ルーティングを実現したいときがあります。
その場合、API Gateway から連携したイベントマッピングは以下のような APIGatewayRestResolver を初期化した後に、デコレーターで URL パスと関数のマッピングをおこなっています。
OpenAPI 定義で、API に対してある程度の入力と出力などの型の制約を設けることができるようです。
別の要件で、Lambda の前段にあるイベントソースの API Gateway を ALB にかえたいという場合は、APIGatewayRestResolver を ALBResolver に変えることで、イベントソースからわたってきたペイロードの型をリソースにあわせて吸収してくれるようです。
なお、Event Handler については、Python のみで利用可能なものになっていますが、2025 年第一四半期に Powertools の TypeScript 側でもリリースされるようです。
私はメインで Node.js をランタイムに使っていることがおおいので、楽しみです。
冪等性の保証
Lambda のべき等性についても言及がありました。
べき等性とは、ある操作を何度繰り返しても同じ結果が得られる性質のことです。
Lambda のベストプラクティスでも、べき等であるコードを記述することが求められています。
冪等性コードを記述します。関数の記述に冪等性コードを使用すると、重複するイベントが同じ方法で処理されるようになります。コードでは、イベントを適切に検証し、重複するイベントを適切に処理する必要があります。
このべき等性を保証する方法は、Powertools としても用意しているようでした。
aws_lambda_powertools.utilities.idempotency というメソッドと状態を保持するための DynamoDB を新規で作成する必要があるようです。
ライブラリでべき等性を保証してくれるのはかなり便利ですね。
以下の AWS のブログにも具体的な実装方法の例がありました。
さいごに
以上、「Gain expert-level knowledge about Powertools for AWS Lambda」というセッションのレポートでした。
Powertools を使って、Lambda をベースにしたサーバレスアプリケーションの品質を上げるためのいくつかのアプローチが知れるセッションでした。
Wide Logs という概念であったり、べき等性を保証する方法について初めて知ることが多かったため実際に手を動かして試してみたいです。
この記事がどなたかの参考になれば幸いです。