Open3
AWS Lambda学習記録
Lambdaを学ぶ目的
- 10年使われているサービスで、今後も使われていきそう
- 小さいプロダクトを作るところからAWSを学べる気がする
- 汎用性が高いサービスだから、これを学ぶと汎用性が上がりそう
- サーバレスアプリケーションに興味ある
参考資料
Lambdaを使用するタイミング
上記資料から引用
- ファイル処理: Amazon Simple Storage Service (Amazon S3) を使用して、アップロード後に Lambda データ処理をリアルタイムでトリガーします。
- ストリーム処理: Lambda と Amazon Kinesis を使用して、アプリケーションアクティビティの追跡、取引注文の処理、クリックストリーム分析、データクレンジング、ログのフィルタリング、インデックス作成、ソーシャルメディア分析、モノのインターネット (IoT) デバイスデータのテレメトリ、および計測のためにリアルタイムのストリーミングデータを処理します。
- ウェブアプリケーション: Lambda と他の AWS サービスを組み合わせて、自動的にスケールアップおよびスケールダウンし、複数のデータセンターにまたがる高可用性設定で実行される強力なウェブアプリケーションを構築します。
- IoT バックエンド: Lambda を使用してサーバーレスバックエンドを構築し、ウェブ、モバイル、IoT、およびサードパーティの API リクエストを処理します。
- モバイルバックエンド: Lambda と Amazon API Gateway を使用してバックエンドを構築し、API リクエストを認証して処理します。AWS Amplify を使用すると、iOS、Android、ウェブ、React Native フロントエンドと簡単に統合できます。
最初のLambda関数を作成する
やったこと
- 関数を作成
- ブラウザ上のエディタでコード編集とデプロイ
- テスト用のラムダのトリガイベントを作成と実行
コンテナイメージのデプロイ
ランタイムインターフェイスクライアントで代替ベースイメージを使用する
例となったDockerfileがマルチステージビルドの教材としてとても参考になった。
# グローバルスコープでの定義
# 定義されたARGは各ステージで自動的に共有されない
ARG FUNCTION_DIR="/function"
# ステージ1:build-image
# このステージは依存関係のインストール用のステージ
FROM python:3.12 AS build-image
# ARGを再度宣言
ARG FUNCTION_DIR
RUN mkdir -p ${FUNCTION_DIR}
COPY . ${FUNCTION_DIR}
# 指定されたディレクトリ (${FUNCTION_DIR}) にインストール
RUN pip install --target ${FUNCTION_DIR} awslambdaric
# ステージ2:最終イメージ
FROM python:3.12-slim
# ARGを再度宣言
ARG FUNCTION_DIR
WORKDIR ${FUNCTION_DIR}
# ステージ1からコピーさせる
COPY ${FUNCTION_DIR} ${FUNCTION_DIR}
# ENTRYPOINTはコンテナ起動時必ず実行される
ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
# CMDはENTRYPOINTへ引数として渡される
# 最終的には下記が実行される
# /usr/local/bin/python -m awslambdaric lambda_function.handler
CMD [ "lambda_function.handler" ]
CMDとENTRYPOINTの違いを理解した。
Docker Best Practices: Choosing Between RUN, CMD, and ENTRYPOINT | Docker
Python の Lambda 関数ハンドラーの定義
def handler_name(event, context):
...
return some_value
- デフォルトはlambda_function.pyの
lambda_handler
- ファイル名やハンドラー名を変える場合は編集が必要
引数
event
- イベントオブジェクト:JSON形式ドキュメント
下記のような構造をしている。
Pythonだと辞書で取得すれば良さそう
{
"TemperatureK": 281,
"WindKmh": -3,
"HumidityPct": 0.55,
"PressureHPa": 1020
}
{
"Records": [
{
"Sns": {
"Timestamp": "2019-01-02T12:45:07.000Z",
"Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"Message": "Hello from SNS!",
...
context
ランタイムから渡されるオブジェクト
Lambda コンテキストオブジェクトを使用して Python 関数の情報を取得する - AWS Lambda
import time
def lambda_handler(event, context):
print("Lambda function ARN:", context.invoked_function_arn)
print("CloudWatch log stream name:", context.log_stream_name)
print("CloudWatch log group name:", context.log_group_name)
print("Lambda Request ID:", context.aws_request_id)
print("Lambda function memory limits in MB:", context.memory_limit_in_mb)
# We have added a 1 second delay so you can see the time remaining in get_remaining_time_in_millis.
time.sleep(1)
print("Lambda time remaining in MS:", context.get_remaining_time_in_millis())
ベストプラクティス
- コアロジックと分けること
- 1つの巨大なlambda_handlerにしないこと
- 再帰呼び出ししないこと
- 冪等性にすること