はじめに
「S3に画像をアップロードしたら、自動で中身を分析してほしい」——そんな仕組みを、AWSコンソールのみでゼロから構築するハンズオンです。
Amazon Rekognition の DetectLabels API を使うと、画像に写っている物体・シーン・動物などを自動で検出できます。犬の写真をアップロードすれば「Dog(信頼度98%)」「Animal(97%)」といったラベルが返ってきます。
ユーザー
↓ JPEG / PNG をアップロード
S3 バケット(UploadBucket)
↓ ObjectCreated イベント(自動)
Lambda(DetectFunction)
↓ rekognition:DetectLabels(S3Object を指定)
Amazon Rekognition
↓ [{"name": "Dog", "confidence": 98.5}, ...] を返す
Lambda
↓ print(JSON)
CloudWatch Logsこのハンズオンで体験できること:
- S3 トリガー — S3 へのアップロードを契機に Lambda を自動起動する仕組み
- Rekognition DetectLabels — 画像内の物体・シーン・動物を検出してラベルと信頼度を返す API
- IAM 権限管理 — Lambda から S3・Rekognition を呼び出すために必要な権限の追加手順
- S3Object 参照 — 画像データを Lambda に転送せず S3 の場所を直接 Rekognition に渡す効率的な方法
この記事は SAM版ハンズオン の比較記事です。
コンソール操作で S3・Lambda・Rekognition の連携を視覚的に学び、SAM と何が違うのかを比較したい方向けです。
キーワード解説
| 用語 | 意味 |
|---|---|
| DetectLabels | Rekognition API。画像内の物体・シーンを検出してラベル名と信頼度を返す |
| 信頼度(Confidence) | ラベルが正確であるかどうかの確度(0〜100%)。今回は70%以上のみ返す |
| S3Object 参照 | 画像データを Lambda に転送せず、S3 の場所を Rekognition に渡す方式 |
| S3 イベント通知 | S3 バケットへのオブジェクト作成・削除などをトリガーに Lambda を呼び出す仕組み |
| 実行ロール | Lambda が他の AWS サービスを操作するために使う IAM ロール |
| 無料枠 | 最初の12ヶ月 / 月5,000枚まで無料。超過後は $0.001/枚 |
使用するAWSサービス
| サービス | 役割 | 料金 |
|---|---|---|
| S3 | 画像のアップロード先バケット | 月5GBまで無料 |
| Lambda | S3 イベントを受けて Rekognition を呼び出す | 月100万リクエスト・400,000 GB-秒まで無料 |
| Rekognition | 画像ラベル検出(DetectLabels) | 最初の12ヶ月 / 月5,000枚まで無料 |
| IAM | Lambda の実行権限管理 | 無料 |
| CloudWatch Logs | Lambda の実行ログ(ラベル検出結果) | 月5GBまで無料 |
全体の作業順序
① S3 バケットを作成する
↓
② Lambda 関数を作成する(コード入力・タイムアウト設定)
↓
③ Lambda の実行ロールに権限を追加する
(S3: GetObject / Rekognition: DetectLabels)
↓
④ Lambda に S3 トリガーを追加する
↓
⑤ 動作テスト(画像をアップロード → ログを確認)
↓
⑥ リソースの削除① S3 バケットを作成する
AWSコンソール → S3 → 「バケットを作成」
| 設定項目 | 値 |
|---|---|
| バケット名 | my-rekognition-upload(グローバルユニークな名前) |
| リージョン | アジアパシフィック(東京)ap-northeast-1 |
| その他 | デフォルトのまま |
「バケットを作成」をクリック。
控えておく情報:
- バケット名(削除時・IAMポリシー設定時に使用)
バケット名のグローバルユニークについて:
S3 のバケット名は全 AWS アカウントで一意である必要があります。my-rekognition-upload-に自分のアカウントIDや日付を追加すると重複を避けられます。
② Lambda 関数を作成する
AWSコンソール → Lambda → 「関数の作成」
| 設定項目 | 値 |
|---|---|
| 作成方法 | 一から作成 |
| 関数名 | DetectFunction |
| ランタイム | Python 3.12 |
| アーキテクチャ | x86_64 |
| 実行ロール | 「基本的な Lambda アクセス権限で新しいロールを作成」(デフォルト) |
「関数の作成」をクリック。
タイムアウトの設定
「設定」タブ → 「一般設定」→「編集」
| 設定項目 | 値 |
|---|---|
| タイムアウト | 30 秒 |
「保存」をクリック。
タイムアウトを 30 秒にする理由:
Rekognition API の呼び出しには数秒かかることがあります。デフォルト(3秒)では Rekognition のレスポンスを待ちきれずタイムアウトするため、余裕を持って 30 秒に設定します。
コードの入力
「コード」タブ → lambda_function.py を開いて既存の内容を全て置き換える。
import json
import urllib.parse
import boto3
rekognition = boto3.client("rekognition")
def lambda_handler(event, context):
for record in event["Records"]:
bucket = record["s3"]["bucket"]["name"]
key = urllib.parse.unquote_plus(record["s3"]["object"]["key"])
print(json.dumps({"status": "start", "bucket": bucket, "key": key}))
response = rekognition.detect_labels(
Image={
"S3Object": {
"Bucket": bucket,
"Name": key,
}
},
MaxLabels=10,
MinConfidence=70,
)
labels = [
{
"name": label["Name"],
"confidence": round(label["Confidence"], 1),
}
for label in response["Labels"]
]
result = {
"bucket": bucket,
"key": key,
"label_count": len(labels),
"labels": labels,
}
print(json.dumps(result, ensure_ascii=False))
return {"processedCount": len(event["Records"])}「Deploy」ボタンをクリックしてコードを保存する。
コードのポイント:
| ポイント | 説明 |
|---|---|
rekognition = boto3.client("rekognition") をグローバルに置く | Lambda のコールドスタート時に1回だけ初期化。ウォームスタート時は再利用されパフォーマンスが向上する |
urllib.parse.unquote_plus(key) | 日本語や空白を含むファイル名は S3 イベントで URL エンコードされるため、デコードが必要 |
S3Object 参照 | 画像データを Lambda のメモリに転送せず S3 の場所を Rekognition に渡す。メモリ効率が良い |
MinConfidence=70 | 信頼度 70% 未満のラベルは結果から除外。全件見たい場合は 0 に変更して Deploy する |
③ Lambda の実行ロールに権限を追加する
デフォルトの実行ロールは CloudWatch Logs への書き込みのみ。
S3 からの読み取りと Rekognition の呼び出し権限を追加する。
Lambda → DetectFunction → 「設定」タブ → 「アクセス権限」→ 実行ロール名のリンクをクリック
(例: DetectFunction-role-XXXX)→ IAM コンソールのロール画面が開く。
3-1. Rekognition 権限を追加する
「許可を追加」→「ポリシーをアタッチ」
検索ボックスに Rekognition と入力 → AmazonRekognitionReadOnlyAccess にチェック → 「許可を追加」。
AmazonRekognitionReadOnlyAccess に含まれる主な権限:
rekognition:DetectLabels— ラベル検出(今回使用)rekognition:DetectFaces— 顔検出rekognition:DetectText— テキスト検出
3-2. S3 GetObject 権限を追加する
「許可を追加」→「インラインポリシーを作成」
「JSON」タブを選択して以下を入力する(my-rekognition-upload を ① のバケット名に変更):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-rekognition-upload/*"
}
]
}「次へ」→ ポリシー名: S3ReadForRekognition → 「ポリシーを作成」。
なぜ S3 の権限が必要か:
Rekognition にS3Objectを指定した場合、Rekognition が Lambda の IAM ロールを借りて
S3 からオブジェクトを取得します。Lambda ロールにs3:GetObjectがないと 403 エラーになります。SAM版では
S3ReadPolicy(SAM 組み込みポリシー)が特定バケットのみにs3:GetObjectを自動付与します。
コンソール版では手動でインラインポリシーを作成する必要があります。
④ Lambda に S3 トリガーを追加する
Lambda → DetectFunction → 「設定」タブ → 「トリガー」→「トリガーを追加」
| 設定項目 | 値 |
|---|---|
| ソース | S3 |
| バケット | my-rekognition-upload(① で作成したバケット) |
| イベントタイプ | すべてのオブジェクト作成イベント(s3:ObjectCreated:*) |
| プレフィックス | 空欄(全ファイルを対象) |
| サフィックス | 空欄(全形式を対象) |
「再帰呼び出し」の確認チェックボックスにチェック → 「追加」をクリック。
再帰呼び出しについて:
Lambda の実行結果を同じバケットに書き込む構成にすると、S3 イベントが再発火して無限ループになります。
今回は S3 への書き込みを行わないため問題ありません。
⑤ 動作テスト
テスト用画像の準備
任意の JPEG または PNG 画像を用意する(例: 犬・猫・風景など)。
ファイルサイズは 15MB 以下 であることを確認する。
画像をアップロードする
方法 A: S3 コンソール
S3 → my-rekognition-upload → 「アップロード」→ ファイルをドラッグ&ドロップ → 「アップロード」
方法 B: AWS CLI
aws s3 cp "C:\Users\yourname\Pictures\dog.jpg" s3://my-rekognition-upload/ --region ap-northeast-1CloudWatch Logs でラベル検出結果を確認する
Lambda → DetectFunction → 「モニタリング」タブ → 「CloudWatch Logs を表示」
最新のロットストリームを開いて以下のような出力を確認する。
{"status": "start", "bucket": "my-rekognition-upload", "key": "dog.jpg"}
{
"bucket": "my-rekognition-upload",
"key": "dog.jpg",
"label_count": 8,
"labels": [
{"name": "Dog", "confidence": 98.5},
{"name": "Pet", "confidence": 98.5},
{"name": "Animal", "confidence": 98.5},
{"name": "Canine", "confidence": 98.5},
{"name": "Mammal", "confidence": 97.2},
{"name": "Golden Retriever", "confidence": 85.3},
{"name": "Grass", "confidence": 76.1},
{"name": "Outdoors", "confidence": 71.4}
]
}
{"processedCount": 1}
MinConfidence: 70の効果:
信頼度 70% 未満のラベルは結果に含まれません。
全ラベルを確認したい場合はMinConfidence=0に変更して「Deploy」する。
複数枚でテストする
aws s3 cp "C:\Users\yourname\Pictures\cat.jpg" s3://my-rekognition-upload/ --region ap-northeast-1
aws s3 cp "C:\Users\yourname\Pictures\city.jpg" s3://my-rekognition-upload/ --region ap-northeast-1各ファイルのアップロードごとに Lambda が起動し、それぞれのラベル検出結果がログに記録される。
無料枠の管理:
AWS コンソール → Billing → 無料利用枠 → 「Amazon Rekognition」で当月の使用枚数を確認できます。
月5,000枚まで無料のため、学習目的のハンズオンでは通常課金されません。
⑥ リソースの削除
課金を止めるために、ハンズオン完了後は必ず削除してください。
1. S3 バケットのオブジェクトを全て削除する
aws s3 rm s3://my-rekognition-upload --recursive --region ap-northeast-12. S3 バケットを削除する
S3 → my-rekognition-upload → 「削除」→ バケット名を入力 → 「削除」
3. Lambda のトリガーを削除する
Lambda → DetectFunction → 「設定」→「トリガー」→ S3 トリガーを選択 → 「削除」
4. Lambda 関数を削除する
Lambda → 関数 → DetectFunction → 「アクション」→「削除」
5. IAM ロールを削除する(任意)
IAM → ロール → DetectFunction-role-XXXX を削除
6. CloudWatch Logs のロググループを削除する(任意)
CloudWatch → ロググループ → /aws/lambda/DetectFunction → 削除
SAM版との大きな違い(SAMのメリット):
SAM版ではsam delete1コマンドで上記すべてのリソースを一括削除できます。
SAMとの対比
| SAMの記述 | コンソールでやること |
|---|---|
AWS::S3::Bucket | S3 → バケットを作成 |
S3ReadPolicy(SAM組み込み) | IAM → ロールにインラインポリシーで s3:GetObject を追加 |
RekognitionDetectOnlyPolicy(SAM組み込み) | IAM → ロールに AmazonRekognitionReadOnlyAccess をアタッチ |
Events: Type: S3(ObjectCreated) | Lambda → トリガーを追加(S3・全オブジェクト作成イベント) |
sam delete | S3を空にしてから削除 + Lambda + IAM + CloudWatch Logs を個別に削除 |
コンソール版のつまずきポイント:
AccessDeniedExceptionが出た場合、S3 の GetObject 権限(インラインポリシー)と Rekognition の DetectLabels 権限(AmazonRekognitionReadOnlyAccess)の両方が揃っているか確認しましょう。どちらか一方が欠けていてもエラーになります。
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
| Lambda が動作しない(ログが出ない) | S3 トリガーが設定されていない | ④ の手順で S3 トリガーを追加する |
AccessDeniedException for Rekognition | Lambda ロールに Rekognition 権限がない | ③-1 の手順で AmazonRekognitionReadOnlyAccess をアタッチ |
AccessDenied for S3 | Lambda ロールに S3 GetObject 権限がない | ③-2 の手順でインラインポリシーを追加 |
InvalidImageFormatException | JPEG/PNG 以外のファイルをアップロードした | JPEG または PNG ファイルを使用する |
ImageTooLargeException | 15MB を超える画像をアップロードした | 15MB 以下の画像を使用する |
| ラベルが 0 件 | MinConfidence が高すぎる | コードの MinConfidence=70 を下げて「Deploy」する |
| 日本語ファイル名でエラー | URL エンコードが解除されていない | コードに urllib.parse.unquote_plus(key) が含まれているか確認 |
| Lambda がタイムアウトする | タイムアウトが短い(デフォルト3秒) | ② の手順でタイムアウトを 30 秒に変更する |
まとめ
今回のハンズオンで体験できたこと:
| 確認項目 | 内容 |
|---|---|
| S3 トリガー | 画像アップロードと同時に Lambda が自動起動する仕組みを体験 |
| Rekognition DetectLabels | 画像に写った物体・動物・シーンが自動でラベル付けされる様子を確認 |
| S3Object 参照 | 画像をLambdaに転送せずS3の場所だけを渡す効率的な連携方法 |
| IAM 権限の設定 | S3・Rekognition それぞれに必要な権限を個別に追加する手順 |
コンソール版で実感できたポイント
- S3 → Lambda → Rekognition という3つのサービスのデータの流れが視覚的に理解できる
- 実行ロールに必要な権限を1つずつ追加することで、IAM の仕組みが身につく
- リソースを個別に作成・削除することで、各サービスの独立性と依存関係が明確になる
コンソール版と SAM 版を比較してみる
コンソールで S3・Lambda・Rekognition の連携を理解したら、SAM で同じ構成をコードで定義することで「SAM が何を自動化しているか」が明確になります。S3ReadPolicy や RekognitionDetectOnlyPolicy による1行での権限付与など、コンソールでの手動操作がコードに対応しています。
コメント