これは何?
AWS Lamdaを触ることになった。とりあえず、なんとなくの雰囲気で実装してみたところ、かなり初歩の段階でエラーが発生した。 この機会なので、学習を兼ねて、まずはちゃんとドキュメントを読んでからエラーの解消にあたって行こうと思い書いてます。
前提
- Rubyで実装しているので、Rubyベースで。
- コードは実務で使っているものになってしまうので、内容を改変・抜粋して掲載しています。(コピペでは動かないと思ってください)
- 公式リファレンスを網羅しているわけではありません。
- AWS SESでLambdaを使用することを前提にしています
AWS Lambdaって何?
- AWS Lambda はサーバーのプロビジョニングや管理をする必要がなく、コードを実行できるコンピューティングサービスです。
- いわゆるサーバーレスアーキテクチャというやつですかね。Lambdaの他に、グーグルの「Google Cloud Functions」、IBMの「OpenWhisk」、マイクロソフトの「Azure Functions」などが挙げられますが、定義がそれぞれ異なるため一概にサーバーレスという言葉でくくることができないのが注意。
- AWSにおけるサーバーレスは「インスタンスベースの仮想サーバー(EC2など)を使わずにアプリケーションを開発するアーキテクチャ」と個人的には解釈しています(間違っていたらご指摘ください)
- 必要な場合にのみ関数を実行する
- 自動的にスケーリング
- 従量課金
- フルマネージドサービス(コードを実行するメモリのバランス、CPU、ネットワーク、その他のリソースを提供するコンピューティングフリート)
- コンピューティングインスタンスにログインしたり、提供されたランタイムのオペレーティングシステムをカスタマイズしたりすることはできない → コンピュートリソースを管理する必要がある場合は向かない
Lambdaの概念
- 関数:Lambda でコードを実行するために呼び出すことができるリソース -トリガー:Lambda 関数を呼び出すリソースまたは設定
- イベント:処理する Lambda 関数のデータを含む JSON 形式のドキュメント。ランタイムによりオブジェクトに変換された上で、関数のコードに渡される。
- ランタイム環境:関数の実行に必要なプロセスとリソースが、実行環境により管理される。
- 命令セットアーキテクチャ:Lambda が関数の実行に使用するコンピュータプロセッサタイプ。2024/02/27時点では、arm64かx86_64が選択できる。
- x86_64に比べるとarm64の方が安価で高パフォーマンスなので特に要件がなければarm64で良さそうです。詳しくはこちらLambda 命令セットアーキテクチャ (ARM/x86) - AWS Lambda
レイヤー:追加のコードまたはデータを含むことができる .zip ファイルアーカイブ。レイヤーには、ライブラリ、 カスタムランタイム 、データ、または設定ファイルを含めることができる。
同時実行
-
- 関数を呼び出したり表示したりするときに、バージョンまたはエイリアスを指定するための修飾子を含めることができる。
- バージョンは、数値修飾子を持つ関数のコードと設定の変更不可能なスナップショット。たとえば、
my-function:1
と指定できる。
今回発生したエラーと対応
{ "errorMessage": "cannot load such file -- lambda_function", "errorType": "Init<LoadError>", "stackTrace": [ "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'" ] }
lambda_functionが存在しないとのことでしたが、Handler設定でデフォルトがlambda_function
として設定されていました。
私のコードではルートディレクトリにhandler.rbファイルを作成し、notifyメソッドを定義していたため、添付画像のような形式になるのが正でした。
AWS SESからどんなデータが渡ってくるのか?
{ "Records": [ { "eventVersion": "1.0", "ses": { "mail": { "commonHeaders": { "from": [ "Jane Doe <janedoe@example.com>" ], "to": [ "johndoe@example.com" ], "returnPath": "janedoe@example.com", "messageId": "<0123456789example.com>", "date": "Wed, 7 Oct 2015 12:34:56 -0700", "subject": "Test Subject" }, "source": "janedoe@example.com", "timestamp": "1970-01-01T00:00:00.000Z", "destination": [ "johndoe@example.com" ], "headers": [ { "name": "Return-Path", "value": "<janedoe@example.com>" }, { "name": "Received", "value": "from mailer.example.com (mailer.example.com [203.0.113.1]) by inbound-smtp.us-west-2.amazonaws.com with SMTP id o3vrnil0e2ic for johndoe@example.com; Wed, 07 Oct 2015 12:34:56 +0000 (UTC)" }, { "name": "DKIM-Signature", "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=example; h=mime-version:from:date:message-id:subject:to:content-type; bh=jX3F0bCAI7sIbkHyy3mLYO28ieDQz2R0P8HwQkklFj4=; b=sQwJ+LMe9RjkesGu+vqU56asvMhrLRRYrWCbV" }, { "name": "MIME-Version", "value": "1.0" }, { "name": "From", "value": "Jane Doe <janedoe@example.com>" }, { "name": "Date", "value": "Wed, 7 Oct 2015 12:34:56 -0700" }, { "name": "Message-ID", "value": "<0123456789example.com>" }, { "name": "Subject", "value": "Test Subject" }, { "name": "To", "value": "johndoe@example.com" }, { "name": "Content-Type", "value": "text/plain; charset=UTF-8" } ], "headersTruncated": false, "messageId": "o3vrnil0e2ic28tr" }, "receipt": { "recipients": [ "johndoe@example.com" ], "timestamp": "1970-01-01T00:00:00.000Z", "spamVerdict": { "status": "PASS" }, "dkimVerdict": { "status": "PASS" }, "processingTimeMillis": 574, "action": { "type": "Lambda", "invocationType": "Event", "functionArn": "arn:aws:lambda:us-west-2:111122223333:function:Example" }, "spfVerdict": { "status": "PASS" }, "virusVerdict": { "status": "PASS" } } }, "eventSource": "aws:ses" } ] }
参考: Amazon SES で AWS Lambda を使用する - AWS Lambda
AWS Lambdaにレイヤーを作成する
coming soon...