S3 に画像がアップロードされたとき、AWS Lambda が自動で画像を縮小し、JPEG のサムネイルを別の S3 バケットへ保存するサンプルです。
このリポジトリは、sharp を Lambda で動かすために Docker を使って Linux 向けの ZIP を作れるようにしてあります。ローカルが Windows や Mac でも、Lambda 用のパッケージを同じ手順で作れます。
- Docker を使った
function.zipの作成はローカルで確認済みです - README の Docker 手順どおりに ZIP を作成できることを確認済みです
- AWS への実デプロイと本番動作確認は、まだ試していません
- 実行時間は現在未計測のため、この README には具体的な性能値を書いていません
この README は、初めて AWS Lambda を触る人でも順番に進められるように作っています。
おすすめの読み方は次の通りです。
- まず
できることを読んで、何を作るかをつかむ - 次に
事前準備を確認する Docker で ZIP を作るを進めるAWS コンソールで設定するを上から順に進める- 最後に
動作確認とトラブルシューティングを見る
スクリーンショットを入れる場合は、各セクションのすぐ下に画像を追加すると見やすくなります。
- S3 に画像をアップロードすると Lambda が自動で実行される
- 画像を指定した横幅にリサイズできる
- 元画像の拡張子に関係なく、出力は常に JPEG になる
- サムネイル名は
元ファイル名-thumbnail.jpgになる
例:
- 入力:
photos/sample.png - 出力:
photos/sample-thumbnail.jpg
- ローカルで Lambda 用の
function.zipを作る - AWS コンソールで Lambda 関数を作る
- ZIP をアップロードする
- 環境変数と IAM 権限を設定する
- S3 のイベント通知を設定する
- 画像をアップロードして動作確認する
- Node.js 20
- AWS Lambda
- Amazon S3
- Docker
- sharp
- AWS SDK for JavaScript v3
├── index.js # Lambda 本体
├── package.json # 依存関係
├── package-lock.json # 依存関係の固定
├── Dockerfile # Lambda 用 ZIP を Docker で作る設定
├── .dockerignore # Docker ビルド時に不要なものを除外
└── README.md # この説明書
- S3 に画像がアップロードされる
- Lambda が起動する
- 元画像を取得する
sharpでリサイズする- JPEG に変換して別バケットへ保存する
Lambda では次の環境変数を使います。
OUTPUT_BUCKET- サムネイル保存先の S3 バケット名
- 必須
RESIZE_WIDTH- リサイズ後の横幅
- 省略時は
100
AWS_REGION- AWS リージョン
- 省略時は
ap-northeast-1
用意するものは次の 2 つです。
- Docker
- AWS アカウント
ここはスクリーンショットを入れるなら、
- Docker Desktop が起動している画面
- AWS マネジメントコンソールにログインした画面
を入れると分かりやすいです。
このプロジェクトのフォルダでターミナルを開きます。
次のコマンドを実行します。
docker build -t lambda-image-resize .ここはスクリーンショットを入れるなら、ターミナルで docker build が成功した画面を入れるとよいです。
docker create --name lambda-image-resize-export lambda-image-resizedocker cp lambda-image-resize-export:/function.zip ./function.zipdocker rm lambda-image-resize-exportフォルダの中に function.zip があれば成功です。
ここはスクリーンショットを入れるなら、エクスプローラーで function.zip が見えている画面を入れると伝わりやすいです。
- AWS マネジメントコンソールにログインします。
- 上部の検索ボックスで
Lambdaと検索します。 Lambdaをクリックします。
ここはスクリーンショットを入れるなら、AWS コンソールの検索欄で Lambda を検索している画面が向いています。
関数を作成を押します。一から作成を選びます。- 次のように設定します。
- 関数名: 好きな名前
- 例:
lambda-image-resize
- 例:
- ランタイム:
Node.js 20.x - アーキテクチャ:
x86_64
デフォルトの実行ロールの変更を開きます。- はじめてなら新しいロールを作る設定のままで構いません。
関数を作成を押します。
ここはスクリーンショットを入れるなら、関数を作成 画面全体が見える画像がよいです。
作成した Lambda 関数の画面で コード タブを開きます。
アップロード元を押します。zip ファイルを選びます。- ローカルで作成した
function.zipを選択します。 - 必要なら
Deployを押します。
ここはスクリーンショットを入れるなら、アップロード元 を押したメニューと ZIP アップロード画面が分かりやすいです。
設定タブを開きます。ランタイム設定を開きます。編集を押します。- ハンドラーが
index.handlerになっていることを確認します。
違っていたら index.handler に直して保存します。
設定タブの環境変数を開きます。編集を押します。環境変数を追加を押します。- 次のように設定します。
- キー:
OUTPUT_BUCKET- 値: 出力用 S3 バケット名
- キー:
RESIZE_WIDTH- 値:
100
- 値:
必要なら次も設定します。
- キー:
AWS_REGION- 値:
ap-northeast-1
- 値:
保存を押します。
ここはスクリーンショットを入れるなら、環境変数 画面が最適です。
- Lambda の
設定タブを開きます。 アクセス権限を開きます。実行ロールに表示されているロール名をクリックします。
- IAM のロール画面で
許可を追加を押します。 インラインポリシーを作成を選ぶか、ポリシー追加画面へ進みます。JSONタブを開きます。- 次のポリシーを貼り付けます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::<入力バケット名>/*",
"arn:aws:s3:::<出力バケット名>/*"
]
}
]
}<入力バケット名>と<出力バケット名>を自分のバケット名に書き換えます。- 保存してロールに追加します。
ここはスクリーンショットを入れるなら、IAM の JSON タブ画面が分かりやすいです。
- AWS コンソールで
S3を開きます。 - 入力用バケットをクリックします。
プロパティタブを開きます。- 下へスクロールして
イベント通知を探します。 イベント通知を作成を押します。- 次のように設定します。
- イベント通知名: 好きな名前
- 例:
resize-trigger
- 例:
- イベントタイプ:
オブジェクトの作成 (すべて) - プレフィックス: 必要なら設定
- 例:
photos/
- 例:
- サフィックス: 必要なら設定
- 例:
.png
- 例:
- 送信先:
Lambda 関数 - Lambda 関数: 作成した関数名
- 保存します。
ここはスクリーンショットを入れるなら、S3 の イベント通知を作成 画面が向いています。
この章は、AWS にデプロイしたあとに行う想定の確認手順です。
- S3 の入力用バケットを開きます。
アップロードを押します。sample.pngなどの画像を 1 枚選びます。アップロードを押します。
数秒待ってから、出力用バケットを開きます。
-thumbnail.jpg のファイルが作成されていれば成功です。
例:
- 入力:
photos/sample.png - 出力:
photos/sample-thumbnail.jpg
ここはスクリーンショットを入れるなら、入力バケットと出力バケットの比較が分かる画面が使いやすいです。
- Lambda 関数画面に戻ります。
モニタリングタブを開きます。CloudWatch Logs を表示を押します。- 最新のログストリームを開きます。
次のようなログがあれば成功です。
Successfully resized image: sample-thumbnail.jpg
ここはスクリーンショットを入れるなら、CloudWatch Logs の成功ログ画面を入れるのがおすすめです。
設定→ランタイム設定- ハンドラーが
index.handlerか確認する
- ハンドラーが
設定→環境変数OUTPUT_BUCKETやRESIZE_WIDTHが正しいか確認する
設定→アクセス権限- IAM ロールに S3 権限があるか確認する
モニタリング- 実行エラーが出ていないか確認する
プロパティ→イベント通知- Lambda が設定されているか確認する
- 入力用バケット
- 本当に画像をアップロードしているか確認する
- 出力用バケット
-thumbnail.jpgが作られているか確認する
- 出力バケット名のスペルミス
- IAM 権限不足
- S3 イベント通知の設定漏れ
- 画像ではないファイルをアップロードしている
RESIZE_WIDTHに文字列や0を入れている
- これは AWS にデプロイして確認できた場合のゴールです
- 入力用バケットに画像を置く
- Lambda が自動で実行される
- 出力用バケットに
-thumbnail.jpg付きファイルが作成される - CloudWatch Logs に成功ログが残る
- 入力バケット名は S3 イベントから取得
- 出力バケット名は
OUTPUT_BUCKETから取得 - リサイズ幅は
RESIZE_WIDTHから取得 - 元画像の拡張子に関係なく、出力は JPEG
photo.sample.pngのようなファイル名でもphoto.sample-thumbnail.jpgになるようにしています
Docker ビルドに不要なものを除外しています。
node_modulesfunction.zip.git.gitignoreREADME.mdnpm-debug.log
これにより、Docker に送るファイルを減らし、ビルドを少し分かりやすくできます。
Windows や Mac でそのまま npm install した node_modules を ZIP に入れると、Lambda の Linux 環境で動かないことがあります。
そのため、このリポジトリでは Docker を使って Linux 向けの ZIP を作ります。
Lambda の環境変数に OUTPUT_BUCKET が設定されていません。保存先バケット名を設定してください。
RESIZE_WIDTH に 100 や 300 のような正の整数を設定してください。
- 複数サイズのサムネイル生成
- WebP など他形式への対応
- CloudFront 連携
- テストコード追加
- CI/CD 対応
- AWS Lambda
- sharp
- README.md: 20260321_Lambda/lambda-image-resize/README.md
README.md内容が実態とあっているか確認 AWSのデプロイは 試していない 実行時間も現在の実態にあわせる。