はじめに
この記事は、SAM版ハンズオン記事の比較版です。
SAM版ではコマンド数本でSQS・DLQ・Lambda・IAM権限がまとめてデプロイできましたが、「SAMが裏で何をやっているのか?」「コンソールで手動操作するとどれだけ手間がかかるのか?」 を実感してもらうために、全く同じ構成をAWSコンソールのみで手作業で構築する手順を解説します。
この記事を読むとわかること:
- SQS・DLQ・Lambda・IAMを個別に設定する依存関係と順序
- SAMが
SQSPollerPolicy1行で解決している IAM 権限設定の実態 - DLQをメインキューに紐づける
RedrivePolicy設定の実際の操作
SAM vs コンソール:どれだけ違うか
| 比較項目 | SAM(コード) | コンソール(手動) |
|---|---|---|
| 操作ステップ数 | 約5ステップ | 6リソース × 複数画面 |
| ARNのコピー | 不要(!GetAtt で自動参照) | DLQ の ARN を手動コピー・貼り付け |
| IAM権限設定 | SQSPollerPolicy 1行 | IAMコンソールでポリシーを手動アタッチ |
| 削除 | sam delete 1コマンド | 5種のリソースを個別に手動削除 |
コンソール操作で学べることの価値:
- IAMロールが「どのサービスが何の権限を持っているか」の具体的なイメージが掴める
- DLQとメインキューの紐付け(RedrivePolicy)の設定画面を実際に見ることができる
- トラブル時に「どのリソースの設定を確認すればよいか」がわかるようになる
構築するもの
SAM版と全く同じ構成・機能のメッセージキュー処理環境を構築します。
送信者(コンソール / AWS CLI)
↓ メッセージ送信
SQS キュー(BatchQueue)
↓ Lambda がポーリング(自動)
Lambda(ProcessFunction / Python 3.12)
↓ 処理成功 → メッセージ削除(自動)
↓ 処理失敗(3回)→ DLQに移動
SQS デッドレターキュー(BatchDLQ)
↓ ログ出力
CloudWatch Logs全体の作業順序
コンソールでは依存する順番通りに作成する必要があります。
① DLQ(BatchDLQ)作成
↓(DLQのARNが必要)
② メインキュー(BatchQueue)作成 + DLQを設定
↓(キューARNが必要)
③ Lambda 関数(ProcessFunction)作成 + コード入力
↓
④ Lambda 実行ロールに SQS 権限を追加
↓
⑤ SQS トリガーを Lambda に追加
↓
⑥ 動作テスト(正常処理 / DLQ振り分け)
⑦ リソースの削除順序が重要な理由:
メインキューの作成時に DLQ の ARN が必要です。
SAMでは!GetAtt BatchDLQ.Arnで自動解決されますが、コンソールでは DLQ を先に作成してARNをコピーしておく必要があります。
① DLQ(デッドレターキュー)作成
AWSコンソール → SQS → 「キューを作成」
1-1. キューの設定
| 設定項目 | 値 |
|---|---|
| タイプ | スタンダード |
| 名前 | BatchDLQ |
「設定」セクション(メッセージ保持期間のみ変更):
| 設定項目 | 値 |
|---|---|
| メッセージ保持期間 | 1 日(デフォルト4日。学習用なので短くしてよい) |
| その他 | デフォルトのまま |
「キューを作成」をクリックします。
控えておく情報:
- DLQ の ARN(例:
arn:aws:sqs:ap-northeast-1:123456789012:BatchDLQ)
SAMとの差分: SAMの
BatchDLQ: Type: AWS::SQS::Queueの部分をコンソールで手動作成しています。SAMでは!GetAtt BatchDLQ.ArnでARNを自動参照できますが、コンソールではここで控えたARNを次のステップで手動入力します。
② メインキュー作成
AWSコンソール → SQS → 「キューを作成」
2-1. キューの設定
| 設定項目 | 値 |
|---|---|
| タイプ | スタンダード |
| 名前 | BatchQueue |
「設定」セクション(可視性タイムアウトのみ変更):
| 設定項目 | 値 |
|---|---|
| 可視性タイムアウト | 180 秒 |
| メッセージ保持期間 | 4 日(デフォルトのまま) |
可視性タイムアウトについて:
Lambda 関数のタイムアウト(30秒)× 6 以上を設定することがAWS推奨です。
処理中にタイムアウトが切れると、同じメッセージが再度キューに現れて二重処理が発生します。
今回は Lambda タイムアウト 30秒 × 6 = 180秒 に設定します。SAMでは
VisibilityTimeout: 180の1行ですが、コンソールでは手動入力が必要です。
2-2. デッドレターキュー(DLQ)の設定
「デッドレターキュー」セクション:
| 設定項目 | 値 |
|---|---|
| デッドレターキューを有効にする | オン |
| デッドレターキューの ARN | ① で控えた BatchDLQ の ARN を貼り付ける |
| 最大受信数(maxReceiveCount) | 3 |
最大受信数(maxReceiveCount)について:
同じメッセージが3回処理を試みて全て失敗した場合、DLQに移動します。
「1回目の失敗 → 可視性タイムアウト後に再試行 → 2回目の失敗 → 再試行 → 3回目の失敗 → DLQへ」という流れです。
SAMではmaxReceiveCount: 3の1行で同じ設定が完了します。
「キューを作成」をクリックします。
控えておく情報:
- BatchQueue の URL(例:
https://sqs.ap-northeast-1.amazonaws.com/123456789012/BatchQueue)
③ Lambda 関数作成
AWSコンソール → Lambda → 「関数の作成」
3-1. 基本設定
| 設定項目 | 値 |
|---|---|
| 作成方法 | 一から作成 |
| 関数名 | ProcessFunction |
| ランタイム | Python 3.12 |
| アーキテクチャ | x86_64 |
| 実行ロール | 「基本的な Lambda アクセス権限で新しいロールを作成」(デフォルトのまま) |
「関数の作成」をクリックします。
3-2. タイムアウトの設定
関数ページ → 「設定」タブ → 「一般設定」→「編集」
| 設定項目 | 値 |
|---|---|
| タイムアウト | 30 秒 |
「保存」をクリックします。
3-3. コードの入力
関数ページ → 「コード」タブ → コードエディタで lambda_function.py を開きます。
既存の内容を全て置き換えて以下を貼り付けます。
import json
import datetime
def lambda_handler(event, context):
results = []
for record in event["Records"]: # SQSからの各メッセージを順番に処理
message_id = record["messageId"]
body = record["body"]
if body.strip().lower() == "error":
raise ValueError(f"意図的なエラー: messageId={message_id}, body={body}")
now = datetime.datetime.now(datetime.timezone.utc)
result = {
"messageId": message_id,
"body": body,
"processedAt": now.isoformat(),
"status": "processed",
}
print(json.dumps(result, ensure_ascii=False))
results.append(result)
print(json.dumps({"processedCount": len(results)}, ensure_ascii=False))
return {"processedCount": len(results), "results": results}「Deploy」ボタンをクリックしてコードを保存します。
④ Lambda 実行ロールに SQS 権限を追加
デフォルトの実行ロールは CloudWatch Logs への書き込みしか持っていません。SQSからメッセージを取り出す権限を手動で追加する必要があります。
Lambda → ProcessFunction → 「設定」タブ → 「アクセス権限」→ 実行ロール名のリンクをクリック
(例: ProcessFunction-role-XXXX)→ IAMコンソールのロール画面が開きます。
「許可を追加」→「ポリシーをアタッチ」
検索ボックスに SQS と入力 → AWSLambdaSQSQueueExecutionRole にチェック → 「許可を追加」をクリックします。
AWSLambdaSQSQueueExecutionRoleに含まれる権限:
sqs:ReceiveMessage— キューからメッセージを取り出すsqs:DeleteMessage— 処理完了後にメッセージを削除するsqs:GetQueueAttributes— キューの属性情報を取得する
SAMとの差分:
SAMではSQSPollerPolicy: QueueName: !GetAtt BatchQueue.QueueNameの2行で上記3権限が自動付与されます。コンソールでは IAMコンソールへの画面遷移 → ポリシー検索 → アタッチの操作が必要です。
⑤ SQS トリガーを Lambda に追加
Lambda → ProcessFunction → 「設定」タブ → 「トリガー」→「トリガーを追加」
| 設定項目 | 値 |
|---|---|
| ソース | SQS |
| SQS キュー | BatchQueue(② で作成したキュー) |
| バッチサイズ | 5 |
| バッチウィンドウ | 0 秒(デフォルト) |
| トリガーの有効化 | オン |
「追加」をクリックします。
バッチサイズとバッチウィンドウについて:
設定 意味 バッチサイズ=5 キューに溜まったメッセージを最大5件まとめてLambdaに渡す バッチウィンドウ=0 メッセージが来たらすぐにLambdaを呼び出す(待機なし) バッチサイズを大きくするとLambdaの呼び出し回数が減りコスト節約になりますが、1件でも失敗するとバッチ全体が再試行される点に注意してください。
SAMとの差分:
SAMのType: SQS/BatchSize: 5の設定がここに対応しています。コンソールではこの「トリガーを追加」画面で手動設定します。
⑥ 動作テスト
6-1. 正常処理テスト
方法A: コンソールからメッセージ送信
SQS → BatchQueue → 「メッセージを送受信」→「メッセージを送信」
| 設定項目 | 値 |
|---|---|
| メッセージ本文 | こんにちは、SQS! |
「メッセージを送信」をクリックします。
方法B: AWS CLI でメッセージ送信
aws sqs send-message ^
--queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/BatchQueue ^
--message-body "こんにちは、SQS!" ^
--region ap-northeast-1CloudWatch Logs でログを確認(数秒後):
Lambda → ProcessFunction → 「モニタリング」タブ → 「CloudWatch Logs を表示」
期待するログ出力:
{"messageId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "body": "こんにちは、SQS!", "processedAt": "2026-02-22T10:00:00.000000+00:00", "status": "processed"}
{"processedCount": 1}"status": "processed" が表示されれば正常処理完了です。
6-2. DLQテスト(失敗メッセージの振り分け確認)
メッセージ本文を error にして送信すると、Lambda が例外を発生させてDLQに移動します。
aws sqs send-message ^
--queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/BatchQueue ^
--message-body "error" ^
--region ap-northeast-1処理の流れ:
- Lambda が
errorを受信 → 例外発生(処理失敗) - 可視性タイムアウト(180秒)が切れると再度キューに現れる
- 3回失敗 →
BatchDLQに移動
注意:DLQに移動するまで最大180秒 × 3回 = 最大9分かかります。
すぐに確認したい場合は、BatchQueue の可視性タイムアウトを一時的に短く(例: 10秒)して再試行するとよいです。
DLQにメッセージが届いたか確認:
SQS → BatchDLQ → 「メッセージを送受信」→「メッセージをポーリング」
error のメッセージが表示されれば DLQ動作確認完了です。
⑦ リソースの削除
課金を止めるために、ハンズオン完了後は必ず削除してください。
1. Lambda のトリガー(SQSイベントソースマッピング)を削除する
Lambda → ProcessFunction → 「設定」タブ → 「トリガー」→ SQSトリガーを選択 → 「削除」
2. Lambda 関数を削除する
Lambda → 関数 → ProcessFunction を選択 → 「アクション」→「削除」→ 確認テキストを入力 → 「削除」
3. SQS キューを削除する(メインキューを先に、次にDLQ)
SQS → BatchQueue を選択 → 「削除」→ キュー名を入力 → 「削除」
SQS → BatchDLQ を選択 → 「削除」→ キュー名を入力 → 「削除」
4. IAM ロールを削除する(任意)
IAM → ロール → ProcessFunction-role-XXXX を選択 → 「削除」→ ロール名を入力 → 「削除」
Lambda を削除しても自動作成された IAM ロールはそのまま残ります。厳密に削除したい場合は IAM コンソールで手動削除します。
5. CloudWatch Logs のロググループを削除する(任意)
CloudWatch → ロググループ → /aws/lambda/ProcessFunction → 「アクション」→「ロググループの削除」
SAMとの差分:
SAMのsam deleteはCloudFormationスタックを削除することで、SQS×2・Lambda・IAMロール・S3を一括削除します。コンソールでは上記5手順を個別に実行する必要があります。
SAMとの対比まとめ
| SAMの記述 | コンソールでやること |
|---|---|
BatchDLQ: Type: AWS::SQS::Queue | SQS → キューを作成(BatchDLQ) |
RedrivePolicy: maxReceiveCount: 3 | メインキューのDLQ設定で「最大受信数 = 3」を入力 |
VisibilityTimeout: 180 | メインキューの設定で可視性タイムアウト = 180秒を入力 |
SQSPollerPolicy(SAM組み込み) | IAMコンソールで AWSLambdaSQSQueueExecutionRole を手動アタッチ |
Type: SQS イベント / BatchSize: 5 | Lambda → トリガー追加(SQS・バッチサイズ5) |
sam delete | Lambda・SQS×2・IAMロール・ロগগループを個別に削除 |
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
| Lambdaが実行されない | 実行ロールにSQS権限がない | ④ の手順で AWSLambdaSQSQueueExecutionRole をアタッチ |
| メッセージがキューに残り続ける | SQSトリガーが設定されていない | ⑤ の手順でトリガーを追加する |
| DLQにメッセージが届かない | 可視性タイムアウトが長すぎて待機中 | しばらく待つ(最大180秒 × 3回 ≒ 9分) |
| Lambda が 500 エラー | コードの構文エラーなど | CloudWatch Logs でエラー内容を確認 |
error 送信後すぐにDLQを確認したい | 可視性タイムアウトが長い | テスト目的でキューの可視性タイムアウトを10秒に変更する |
まとめ
コンソール操作で確認できたこと
コンソール操作を通じて、SAMが裏側で自動処理している内容が明確になりました:
| SAMの記述 | コンソールでやること |
|---|---|
SQSPollerPolicy(1行) | IAMコンソールでポリシーを手動検索・アタッチ |
!GetAtt BatchDLQ.Arn(自動参照) | DLQ作成後にARNをコピー・貼り付け |
sam delete(1コマンド) | 5種のリソースを個別に手動削除 |
どちらを使うべきか
| シーン | 推奨 |
|---|---|
| 本番環境・チーム開発 | SAM(再現性・Git管理・速度) |
| AWSを初めて学ぶ | コンソール(IAMや各サービスの設定の意味を理解する) |
| 構築済みリソースの確認・デバッグ | コンソール(目視確認) |
| 同じ構成を繰り返しデプロイ | SAM(ミスゼロ・自動化) |
関連記事
- SAM版ハンズオン — コマンド数本でSQS + Lambda + DLQ環境を構築

コメント