1.はじめに
1.1.はじめに
Lambdaに対してコンテナイメージのデプロイの経験がないのでハンズオンをしていきます。
1.2.Lambda コンテナの利点とは?
項番 | 項目名 | 詳細 |
---|---|---|
1 | サイズ制限の緩和 | コンテナイメージでのデプロイ: 10GB まで対応(従来 50MB(解凍後250MB)) |
2 | 開発の柔軟性 | Lambdaが公式にサポートしていない言語やバージョン、独自のライブラリ・フレームワークの組込みが可能 |
1.3.本ブログの構築イメージ
- 本ブログの構成を記載する。
2.ハンズオン
2.1.前提
2.1.1.実行環境
- AWS CloudShell 環境
- Docker、AWS CLIはプリインストール済み
- リージョン:バージニア北部
2.1.2.CloudShell環境スペック
項目 | 上限値 |
---|---|
CPU | 1 vCPU(仮想CPU) |
メモリ | 2 GiB RAM |
ストレージ | 1 GBの永続ストレージ(※120日間アクセスがない場合は自動削除) |
セッション時間 | 最大12時間(無操作で20分で自動休止) |
2.2.アプリケーションのコード作成
2.2.1.Lambda_function.py作成
Hello from {message}
を返すLambda- 同内容のレスポンスをする場合、キャッシュが利用されるため回答に時間を含める
# プロジェクトディレクトリ作成・移動
mkdir my-python-lambda && cd my-python-lambda
# アプリケーションコード作成
cat > lambda_function.py << EOF
import json
from datetime import datetime
import pytz
def lambda_handler(event, context):
# 東京時間の取得
tokyo_tz = pytz.timezone('Asia/Tokyo')
current_time = datetime.now(tokyo_tz).strftime('%Y-%m-%d %H:%M:%S %Z')
# メッセージを取得(event パラメータから'message'キーを取得)
message = event.get('message', 'Default message from Lambda!')
return {
'statusCode': 200, # HTTP ステータスコード
'body': json.dumps({
'greeting': f'Hello from {message}!',
'event': event, # 受け取ったイベント全体を返す(デバッグ用)
'requested_at': datetime.now(tokyo_tz).isoformat(), # ISO形式の日時
'display_time': current_time, # 見やすい形式の日時
'request_id': context.aws_request_id # Lambdaリクエストの一意なID
})
}
EOF
2.2.2.requirements.txt作成
pytz
タイムゾーン処理に特化したライブラリ
# 必要パッケージを記載
cat > requirements.txt << EOF
pytz
EOF
2.2.3.Dockerfile作成
# Dockerfile作成
cat > Dockerfile << EOF
# AWS公式よりPython 3.11 環境を利用
FROM public.ecr.aws/lambda/python:3.11
# アプリケーションコードをコピー
COPY lambda_function.py requirements.txt ./
# 依存関係をインストール
RUN pip install --no-cache-dir -r requirements.txt
# ハンドラを設定
CMD ["lambda_function.lambda_handler"]
EOF
2.3.ECR作成
2.3.1.ECRリポジトリ作成
# 変数設定
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REPO_NAME="lambda-container"
REGION=us-east-1
# ECRリポジトリ作成
aws ecr create-repository --repository-name $REPO_NAME
# ECRにログイン
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com
2.4.Dockerイメージ作成
2.4.1.ビルド・プッシュ手順
# 変数設定
ECR_IMAGE_URI=$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME
# Dockerイメージビルド
docker build -t $ECR_IMAGE_URI:latest .
# ECRにプッシュ
docker push $ECR_IMAGE_URI:latest
2.4.2.【参考】古いイメージ削除する場合
イメージは残置されリソースを圧迫するため、適宜以下のコマンドで古いリソースを削除する
# イメージの一覧を出力
docker images
# 特定のイメージを削除(各イメージのプレフィックスには、各自のアカウントIDが挿入されている)
docker rmi ${AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container:latest
# 古いイメージ(最新バージョンがあるもの)を削除
docker image prune
# 全てのイメージを削除。他のプロジェクトで使用中のイメージも削除される可能性があるため、使用は慎重に実行する。
docker system prune -a
2.5.Lambda関数デプロイ
2.5.1.Lambda用 IAMロール作成
# IAMロール作成
aws iam create-role --role-name lambda-container-role --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
# IAMポリシーをアタッチ
aws iam attach-role-policy \
--role-name lambda-container-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
# IAMロールARNを取得
ROLE_ARN=$(aws iam get-role --role-name lambda-container-role --query 'Role.Arn' --output text)
2.5.2.Lambda作成
2.5.2.1.Lambdaの設定値
項目 | 設定値 | 説明 |
---|---|---|
function-name | my-python-container-function | Lambda関数名 |
role | $ROLE_ARN | IAMロールARN |
code | ImageUri=$ECR_IMAGE_URI | コンテナイメージURI |
description" | Python Lambda Container from CloudShell" | 関数の説明文 |
timeout | 30 | タイムアウト(秒) |
memory-size | 256 | メモリサイズ(MB) |
package-type | Image | デプロイパッケージタイプ |
region | $REGION | デプロイ先のリージョン |
2.5.2.2.Lambda関数の作成
# Lambda関数を作成
aws lambda create-function \
--function-name my-python-container-function \
--role $ROLE_ARN \
--code ImageUri=$ECR_IMAGE_URI:latest \
--description "Python Lambda Container from CloudShell" \
--timeout 30 \
--memory-size 256 \
--package-type Image \
--region $REGION
# 2回目以降のコマンド((イメージ更新時に使用)
aws lambda update-function-code \
--function-name my-python-container-function \
--image-uri $ECR_IMAGE_URI:latest \
--region $REGION
2.6.挙動確認
2.6.1.コマンド実行
"StatusCode": 200
が返ってくることを確認
# テストイベントを作成
echo '{"key": "value", "message": "Lambda Container"}' > test-event.json
# Lambda関数の呼出し
aws lambda invoke \
--function-name my-python-container-function \
--payload fileb://test-event.json \
response.json
# レスポンスの確認
cat response.json
2.6.2.実行結果
2.6.2.1.コンソールの出力
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
2.6.2.2.response.jsonの内容
- 適宜改行して記載
{
"statusCode": 200,
"body":
"{
\"greeting\": \"Hello from Lambda Container!\",
\"event\": {
\"key\": \"value\",
\"message\": \"Lambda Container\"
},
\"requested_at\": \"2025-05-05T08:20:55.071375+09:00\",
\"display_time\": \"2025-05-05 08:20:55 JST\",
\"request_id\": \"8f192969-b9b3-4679-abb6-0c3cf307dd92\"
}"
}
3.おわりに
3.1.得られた知見
- コンテナイメージを利用した、Lambdaのデプロイ方法
- 同一イベントによるキャッシュ問題への対応(タイムスタンプ付加など)
3.2.今後の課題
- ECS/EKS との比較検討
- コンテナベース開発の発展(CI/CDパイプライン)
3.3.サンプルコード
本ハンズオンで使用したコードは以下のリポジトリで公開しています: