0
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?

AWS Lambda コンテナデプロイ入門 ~CloudShellで始めるハンズオン~

Posted at

1.はじめに

1.1.はじめに

Lambdaに対してコンテナイメージのデプロイの経験がないのでハンズオンをしていきます。

1.2.Lambda コンテナの利点とは?

項番 項目名 詳細
1 サイズ制限の緩和 コンテナイメージでのデプロイ: 10GB まで対応(従来 50MB(解凍後250MB))
2 開発の柔軟性 Lambdaが公式にサポートしていない言語やバージョン、独自のライブラリ・フレームワークの組込みが可能

1.3.本ブログの構築イメージ

  • 本ブログの構成を記載する。

uploading...0

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.サンプルコード

本ハンズオンで使用したコードは以下のリポジトリで公開しています:

0
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
0
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?