AWSコンソールだけでSQS + Lambdaキュー処理を構築する手順【SAM版との比較付き】

AWS Basic
スポンサーリンク
スポンサーリンク

はじめに

この記事は、SAM版ハンズオン記事の比較版です。

SAM版ではコマンド数本でSQS・DLQ・Lambda・IAM権限がまとめてデプロイできましたが、「SAMが裏で何をやっているのか?」「コンソールで手動操作するとどれだけ手間がかかるのか?」 を実感してもらうために、全く同じ構成をAWSコンソールのみで手作業で構築する手順を解説します。

この記事を読むとわかること:

  • SQS・DLQ・Lambda・IAMを個別に設定する依存関係と順序
  • SAMが SQSPollerPolicy 1行で解決している IAM 権限設定の実態
  • DLQをメインキューに紐づける RedrivePolicy 設定の実際の操作

スポンサーリンク

SAM vs コンソール:どれだけ違うか

比較項目SAM(コード)コンソール(手動)
操作ステップ数約5ステップ6リソース × 複数画面
ARNのコピー不要(!GetAtt で自動参照)DLQ の ARN を手動コピー・貼り付け
IAM権限設定SQSPollerPolicy 1行IAMコンソールでポリシーを手動アタッチ
削除sam delete 1コマンド5種のリソースを個別に手動削除

コンソール操作で学べることの価値:

  • IAMロールが「どのサービスが何の権限を持っているか」の具体的なイメージが掴める
  • DLQとメインキューの紐付け(RedrivePolicy)の設定画面を実際に見ることができる
  • トラブル時に「どのリソースの設定を確認すればよいか」がわかるようになる

Amazon検索[本 AWS 開発]

スポンサーリンク

構築するもの

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-1

CloudWatch 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

処理の流れ:

  1. Lambda が error を受信 → 例外発生(処理失敗)
  2. 可視性タイムアウト(180秒)が切れると再度キューに現れる
  3. 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::QueueSQS → キューを作成(BatchDLQ)
RedrivePolicy: maxReceiveCount: 3メインキューのDLQ設定で「最大受信数 = 3」を入力
VisibilityTimeout: 180メインキューの設定で可視性タイムアウト = 180秒を入力
SQSPollerPolicy(SAM組み込み)IAMコンソールで AWSLambdaSQSQueueExecutionRole を手動アタッチ
Type: SQS イベント / BatchSize: 5Lambda → トリガー追加(SQS・バッチサイズ5)
sam deleteLambda・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環境を構築
AWSハンズオン - SQS + Lambdaでメッセージキュー処理を実装しよう【SAM版 / Windows対応】
はじめに「メッセージキューって何に使うの?」「エラーが起きたメッセージをどうやって管理するの?」という疑問を持っている方向けに、Amazon SQS + Lambda によるメッセージキュー処理をゼロから構築するハンズオンを紹介します。今回...

Amazon検索[本 AWS 開発]

コメント