ヤマムギ

growing hard days.

*

ハンズオン: サーバーレスアーキテクチャ ~AWS認定デベロッパーアソシエイト(DCA-C02)~

   

このブログは2026年6月29日翔泳社さんより発売される「AWS教科書 AWS認定デベロッパーアソシエイト テキスト&問題集」で扱う内容を体験していただくためのハンズオンガイドです。

このハンズオンガイドでは、サーバーレスアーキテクチャを構成する主要サービス(S3、DynamoDB、Lambda、API Gateway、SNS、SQS)を使って、アンケートフォームのバックエンドを構築します。各タスクでサービスを1つずつ作成し、最終的にそれらを組み合わせて動作させます。

全体構成

東京リージョンで構築してください。
完成するアーキテクチャは以下のとおりです。

(1) S3バケットに静的なHTMLアンケートフォームを配置して公開する
(2) フォームからAPI Gateway(REST API)にPOSTリクエストを送信する
(3) API Gatewayが受付用Lambda関数を実行する
(4) 受付用Lambda関数がSNSトピックにメッセージをパブリッシュする
(5) SNSトピックからSQSキューにメッセージがファンアウトされる
(6) SNSトピックからメール通知が送信される(フィルターポリシーで評価1のみ)
(7) SQSキューをトリガーに書き込み用Lambda関数が実行される
(8) 書き込み用Lambda関数がDynamoDBテーブルにアンケート内容を保存する

アンケートフォームでは「感想(自由記述)」と「友達に勧めたいかどうかの5段階評価」を入力します。
評価が1(最低評価)の回答があった場合のみ、管理者にメール通知が届くようにSNSのサブスクリプションフィルターを設定します。

準備:IAMポリシーの作成とアタッチ

ハンズオンで使用するIAMユーザーまたはIAMロールに、以下のポリシーをアタッチしてください。

タスク 1:DynamoDBテーブルを作成する

目的

アンケート回答を保存するDynamoDBテーブルを作成しましょう。グローバルセカンダリインデックス(GSI)も作成して、評価段階での検索を可能にします。

手順

(1) マネジメントコンソール上部の検索フィールドにDynamoDBと入力し、DynamoDBコンソールにアクセスします。
(2) リージョンがap-northeast-1(東京)であることを確認します。
(3) 左メニューから[テーブル]-[テーブルの作成]をクリック。
(4) 以下の設定を行います:

項目 設定値
テーブル名 SurveyResponses
パーティションキー ResponseId (文字列)
ソートキー ResponseDate (文字列)
テーブル設定 設定をカスタマイズ
読み込み/書き込みキャパシティモード オンデマンド

(5) [セカンダリインデックス]セクションで[グローバルインデックスの作成]をクリック。
(6) 以下の設定でGSIを作成します:

項目 設定値
パーティションキー Rating (数値)
ソートキー ResponseDate (文字列)
インデックス名 Rating-ResponseDate-index

(7) [インデックスを作成]をクリック。
(8) [テーブルの作成]をクリック。
(9) テーブルのステータスがアクティブになることを確認します。

ポイント

  • パーティションキー(ResponseId)とソートキー(ResponseDate)の組み合わせでプライマリキーを構成しています。
  • GSIを作成することで、評価段階(Rating)をキーにした検索が可能になります。例えば「評価1の回答だけを抽出する」といったクエリが効率的に実行できます。
  • オンデマンドモードはリクエスト数に応じた課金なので、開発やテスト用途に適しています。

タスク 2:SNSトピックを作成する

目的

アンケート回答を受け付けたときに通知を配信するためのSNSトピックを作成しましょう。

手順

(1) マネジメントコンソール上部の検索フィールドにSNSと入力し、Amazon SNSコンソールにアクセスします。
(2) 左メニューから[トピック]-[トピックの作成]をクリック。
(3) 以下の設定を行います:

項目 設定値
タイプ スタンダード
名前 SurveyNotification

(4) その他の設定はデフォルトのまま[トピックの作成]をクリック。
(5) トピックが作成されたら、トピックARNをメモしておきます。

ポイント

  • SNSはPub/Sub(パブリッシュ/サブスクライブ)モデルのメッセージングサービスです。
  • このあとのタスクで、メール通知とSQSキューの2つのサブスクリプションを追加します。

タスク 3:SQSキューを作成してSNSにサブスクライブする

目的

アンケート回答をDynamoDBに書き込むための中間キューとして、SQSキューを作成しましょう。SNSからのサブスクリプションとして設定します。

手順

(1) マネジメントコンソール上部の検索フィールドにSQSと入力し、Amazon SQSコンソールにアクセスします。
(2) まずデッドレターキューを作成します。[キューを作成]をクリック。
(3) 以下の設定を行います:

項目 設定値
タイプ 標準
名前 SurveyQueue-DLQ

(4) その他の設定はデフォルトのまま[キューを作成]をクリック。
(5) 次にメインのキューを作成します。[キューを作成]をクリック。
(6) 以下の設定を行います:

項目 設定値
タイプ 標準
名前 SurveyQueue
可視性タイムアウト 60秒
メッセージ保持期間 4日(デフォルト)

(7) [デッドレターキュー]セクションで以下を設定します:

項目 設定値
デッドレターキューの有効化 オン
キューの選択 SurveyQueue-DLQ
最大受信数 3

(8) [キューを作成]をクリック。
(9) キューが作成されたら、SurveyQueueのARNをメモしておきます。
(10) 次に、SNSトピックからこのキューにメッセージを送信できるようにします。SNSコンソールに移動し、SurveyNotificationトピックを開きます。
(11) [サブスクリプションの作成]をクリック。
(12) 以下の設定を行います:

項目 設定値
プロトコル Amazon SQS
エンドポイント SurveyQueueのARN
rawメッセージ配信の有効化 チェックを入れる

(13) [サブスクリプションの作成]をクリック。

これでSNSトピックにパブリッシュされたメッセージが、SQSキューに配信されるようになります。
SNSコンソールからサブスクライブすると、キューポリシー(SNSからのSendMessage許可)も自動的に設定されます。
rawメッセージ配信を有効にすることで、SNSのメタデータなしでメッセージ本文だけがキューに送信されます。

ポイント

  • SQSはメッセージキューサービスで、サービス間の疎結合化を実現します。
  • SNSとSQSを組み合わせたファンアウトパターンにより、1つのメッセージを複数の処理に並列で配信できます。
  • rawメッセージ配信を有効にすることで、後続のLambda関数のコードがシンプルになります。
  • デッドレターキュー(DLQ)を設定することで、処理に3回失敗したメッセージがDLQに移動します。DLQのメッセージを確認して問題の調査ができます。
  • 可視性タイムアウトを60秒に設定して、並列実行されるLambda関数がメッセージを重複受信しないようにしています。
  • キューを挟むことで、DynamoDBへの書き込みが一時的に失敗しても、メッセージがキューに残りリトライできます。

タスク 4:SNSにメール通知サブスクリプションを追加する(フィルターポリシー付き)

目的

評価が1(最低評価)の回答があったときだけ管理者にメール通知が届くように、サブスクリプションフィルターを設定しましょう。

手順

(1) SNSコンソールでSurveyNotificationトピックを開きます。
(2) [サブスクリプションの作成]をクリック。
(3) 以下の設定を行います:

項目 設定値
プロトコル Eメール
エンドポイント 自分のメールアドレス

(4) [サブスクリプションフィルターポリシー]セクションを展開します。
(5) [サブスクリプションフィルターポリシー]を有効にして、フィルターポリシーの適用先に[メッセージ属性]を選択します。
(6) 以下のJSONを入力します:

(7) [サブスクリプションの作成]をクリック。
(8) 入力したメールアドレスに確認メールが届くので、メール内の[Confirm subscription]リンクをクリックして確認します。

ポイント

  • サブスクリプションフィルターポリシーを使うと、メッセージ属性の値に基づいて特定のサブスクリプションにだけメッセージを配信できます。
  • この設定により、評価が1の回答があったときだけ管理者にメールが届きます。評価2〜5の回答ではメールは送信されません。
  • フィルターポリシーはSNS側で評価されるため、不要なメッセージがサブスクリプションに届くことを簡単に防げます。
  • パブリッシュ時にメッセージ属性としてratingを設定する必要があります(受付用Lambda関数で対応します)。

タスク 5:受付用Lambda関数を作成する

目的

API Gatewayからのリクエストを受け取り、SNSトピックにアンケート内容をパブリッシュする受付用Lambda関数を作成しましょう。

手順

(1) Lambdaコンソールにアクセスし、[関数の作成]をクリック。
(2) 以下の設定を行います:

項目 設定値
作成方法 一から作成
関数名 SurveyReceiver
ランタイム Python 3.14
アーキテクチャ x86_64

(3) [関数の作成]をクリック。
(4) 関数が作成されたら、[設定]タブ-[アクセス権限]をクリックし、ロール名のリンクをクリックしてIAMコンソールを開きます。
(5) [許可を追加]-[インラインポリシーを作成]をクリックし、[JSON]タブで以下のポリシーを貼り付けます。

(6) ポリシー名をSurveyReceiverSNSPolicyとして保存します。
(7) Lambdaコンソールに戻り、[コード]タブでコードエディタに以下のコードを貼り付けます:

(8) [Deploy]をクリックしてコードをデプロイします。
(9) バージョンを発行します。[バージョン]タブ-[新しいバージョンを発行]をクリックし、説明に「初回リリース」と入力して[発行]をクリック。
(10) エイリアスを作成します。[エイリアス]タブ-[エイリアスを作成]をクリックし、以下を設定します:

項目 設定値
名前 prod
バージョン 1

(11) [保存]をクリック。
(12) [テスト]タブでテストイベントを作成して動作確認します。以下のJSONをテストイベントに設定します:

(13) [テスト]をクリックして実行し、ステータスコード200が返ることを確認します。

ポイント

  • この関数はSNSにパブリッシュするだけのシンプルな受付処理です。実際のDB書き込みは後続のLambda関数が担当します。
  • MessageAttributesにratingを数値型で設定することで、SNSのサブスクリプションフィルターが評価値を判定できるようになります。
  • メッセージ本文(Message)はJSON文字列で、後続のSQS→Lambda→DynamoDB書き込みに必要な情報が含まれています。
  • バージョンを発行してエイリアスprodを作成することで、コードの更新時にエイリアスの向き先を変えるだけでリリースやロールバックが可能になります。

タスク 6:書き込み用Lambda関数を作成する

目的

SQSキューからメッセージを受信して、DynamoDBテーブルにアンケート回答を書き込むLambda関数を作成しましょう。

手順

(1) Lambdaコンソールで[関数の作成]をクリック。
(2) 以下の設定を行います:

項目 設定値
作成方法 一から作成
関数名 SurveyWriter
ランタイム Python 3.14
アーキテクチャ x86_64

(3) [関数の作成]をクリック。
(4) [設定]タブ-[アクセス権限]をクリックし、ロール名のリンクをクリックしてIAMコンソールを開きます。
(5) [許可を追加]-[インラインポリシーを作成]をクリックし、[JSON]タブで以下のポリシーを貼り付けます:

(6) ポリシー名をSurveyWriterPolicyとして保存します。
(7) Lambdaコンソールに戻り、[コード]タブで以下のコードを貼り付けます:

(8) [Deploy]をクリックしてコードをデプロイします。
(9) バージョンを発行します。[バージョン]タブ-[新しいバージョンを発行]をクリックし、説明に「初回リリース」と入力して[発行]をクリック。
(10) エイリアスを作成します。[エイリアス]タブ-[エイリアスを作成]をクリックし、以下を設定します:

項目 設定値
名前 prod
バージョン 1

(11) [保存]をクリック。
(12) prodエイリアスにSQSトリガーを設定します。[エイリアス]タブでprodをクリックし、[設定]タブ-[トリガー]-[トリガーを追加]をクリック。
(13) 以下の設定を行います:

項目 設定値
ソース SQS
SQSキュー SurveyQueue
バッチサイズ 10

(14) [追加]をクリック。

ポイント

  • SQSをトリガーにしたLambda関数はプルイベントモデルです。LambdaサービスがSQSキューをポーリングしてメッセージを取得します。
  • Lambda関数のIAMロールにSQSからのReceiveMessage、DeleteMessage権限が必要です。
  • rawメッセージ配信を有効にしているため、パブリッシュしたメッセージ本文がそのまま届きます。コードがシンプルになります。
  • 処理が正常完了すると、Lambdaサービスが自動的にSQSからメッセージを削除します。
  • SQSトリガーをprodエイリアスに設定することで、$LATEST(開発中のコード)ではなく、本番用のバージョンでメッセージが処理されます。

タスク 7:API Gatewayを作成する

目的

アンケートフォームからのリクエストを受け付けるREST APIを作成し、受付用Lambda関数と統合しましょう。

手順

(1) マネジメントコンソール上部の検索フィールドにAPI Gatewayと入力し、API Gatewayコンソールにアクセスします。
(2) [APIの作成]をクリック。
(3) REST APIの[構築]をクリック。
(4) 以下の設定を行います:

項目 設定値
APIの詳細 新しいAPI
API名 SurveyAPI
説明 アンケートフォームAPI
APIエンドポイントタイプ リージョン

(5) [APIを作成]をクリック。
(6) [リソースを作成]をクリックし、リソース名にsurveyと入力します。[CORS(クロスオリジンリソース共有)]にチェックを入れて[リソースを作成]をクリック。
(7) /surveyリソースを選択した状態で[メソッドを作成]をクリック。
(8) 以下の設定を行います:

項目 設定値
メソッドタイプ POST
統合タイプ Lambda関数
Lambdaプロキシ統合 オン
Lambda関数 SurveyReceiver:prod

※ SurveyReceiverのARNを選択して後ろに :prod を書き加えます。

(9) [メソッドを作成]をクリック。

(10) [メソッドリクエスト]タブの右のほうの[テスト]タブにアクセスして、リクエスト本文に次のメッセージを入力して[テスト]ボタンをクリックします。

(11) 結果のステータス 200を確認して、DynamoDBコンソールでSurveyResponsesテーブルの[項目を探索]を開き、データが保存されていることを確認します。テストが成功したらAPIをデプロイします。

(12) [APIをデプロイ]をクリック。
(13) 以下の設定でデプロイします:

項目 設定値
ステージ 新しいステージ
ステージ名 prod

(14) [デプロイ]をクリック。
(15) 表示されるURLの呼び出しをメモします。

例:https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod

(16) CloudShellを開いて、curlコマンドでAPIをテストします:

URLのxxxxxxxxxx部分は自分のAPIのIDに置き換えてください。
成功すると以下のようなレスポンスが返ります。

(17) DynamoDBコンソールでSurveyResponsesテーブルの[項目を探索]を開き、データが保存されていることを確認します。

(18) 次に、評価1でテストしてメール通知が届くことを確認します:

評価1の場合のみ、管理者メールアドレスに通知が届くことを確認してください。
評価2〜5ではメールは届きません。

ポイント

  • API GatewayのREST APIは、HTTPリクエストを受け付けてバックエンドサービスに転送するインターフェースの役割を果たします。
  • Lambdaプロキシ統合を使用すると、リクエスト情報がそのままLambda関数のeventに渡されるので開発が簡単です。
  • CORSを有効にすることで、S3の静的サイトなど別ドメインからのリクエストを許可できます。

タスク 8:S3で静的ウェブサイトをホスティングする

目的

アンケートフォームのHTMLをS3バケットに配置して、静的ウェブサイトとして公開しましょう。

手順

(1) マネジメントコンソール上部の検索フィールドにS3と入力し、S3コンソールにアクセスします。
(2) [バケットを作成]をクリック。
(3) 以下の設定を行います:

項目 設定値
バケット名 survey-form-handson-{自分の名前など一意の文字列}
リージョン ap-northeast-1
パブリックアクセスをすべてブロック チェックを外す

(4) 「現在の設定により、このバケットとバケット内のオブジェクトがパブリックになる可能性があることを承認します。」にチェックを入れます。
(5) [バケットを作成]をクリック。
(6) 作成したバケットを開き、[プロパティ]タブの[静的ウェブサイトホスティング]セクションで[編集]をクリック。
(7) 以下の設定を行います:

項目 設定値
静的ウェブサイトホスティング 有効にする
インデックスドキュメント index.html

(8) [変更の保存]をクリック。
(9) [アクセス許可]タブの[バケットポリシー]セクションで[編集]をクリックし、以下のポリシーを貼り付けます(バケット名は自分のものに置き換えてください):

(10) [変更の保存]をクリック。
(11) CloudShellを開いて、以下のコマンドでHTMLファイルを作成してアップロードします。API_URLの部分は次の手順で置き換えます。

HTMLファイル内のAPI_URLを自分のAPIエンドポイントに書き換えてからアップロードします。

(12) S3バケットにアップロードします:

(13) S3コンソールでバケットの[プロパティ]タブを開き、[静的ウェブサイトホスティング]セクションに表示されているバケットウェブサイトエンドポイントのURLにブラウザでアクセスします。

例:http://survey-form-handson-{自分の名前}.s3-website-ap-northeast-1.amazonaws.com

(14) アンケートフォームが表示されたら、感想を入力して評価を選択し、[送信]をクリックします。
(15) 「アンケートを受け付けました」と表示されることを確認します。
(16) DynamoDBコンソールでデータが保存されていることを確認します。
(17) 評価1で送信して、メール通知が届くことを確認します。

ポイント

  • S3を使うと、Webサーバーを用意せずにHTMLを公開できます。
  • バケットポリシーでパブリックアクセスを許可することで、インターネットからアクセス可能になります。
  • JavaScriptのfetch APIでAPI Gatewayにリクエストを送信しています。CORSが正しく設定されていないとブラウザからのリクエストがブロックされます。
  • 本番環境ではCloudFrontを前段に配置してHTTPS化するのがベストプラクティスです。

タスク 9:GSIを使ってデータを検索する

目的

グローバルセカンダリインデックスを使って、特定の評価段階のアンケート回答を検索してみましょう。

手順

(1) CloudShellで以下のPythonスクリプトを実行して、GSIを使った検索を体験します:

(2) 評価5の回答も検索してみましょう:

(3) GSIがない場合との違いを確認するため、テーブル全体をスキャンしてフィルタリングする方法も試してみましょう:

ポイント

  • GSIを使ったQueryは、必要なパーティションだけを読み込むので効率的です。
  • Scan + FilterExpressionはテーブル全体を読み込んでからフィルタリングするため、データ量が増えるとコストとレイテンシーが増加して非効率です。
  • GSIのパーティションキーにRating(数値)を設定しているので、特定の評価段階での検索が高速に行えます。
  • ソートキーにResponseDateを設定しているので、同じ評価内で日時順に並べたり、特定期間内での検索もできます。

クリーンアップ

ハンズオンで作成したリソースをすべて削除します。以下の順番で削除してください。

(1) Lambda関数のトリガーとイベントソースマッピングの削除

Lambdaコンソールで SurveyWriter関数を開き、[設定]タブ-[トリガー]からSQSトリガーを削除します。

(2) Lambda関数の削除

Lambdaコンソールで以下の関数を削除します:
– SurveyReceiver
– SurveyWriter

(3) API Gatewayの削除

API GatewayコンソールでSurveyAPIを削除します。

(4) SNSトピックの削除

SNSコンソールでSurveyNotificationトピックを削除します。サブスクリプションも自動的に削除されます。

(5) SQSキューの削除

SQSコンソールでSurveyQueueとSurveyQueue-DLQを削除します。

(6) DynamoDBテーブルの削除

DynamoDBコンソールでSurveyResponsesテーブルを削除します。

(7) S3バケットの削除

S3コンソールでバケット内のオブジェクトをすべて削除してから、バケットを削除します。

(8) IAMロールの削除

IAMコンソールで以下のロールを削除します(Lambda関数作成時に自動作成されたもの):
– SurveyReceiver-role-xxxxxxxx
– SurveyWriter-role-xxxxxxxx

(9) ハンズオン用ポリシーの削除

ハンズオン用に作成したIAMポリシーがあれば削除します。

まとめ

タスク サービス 役割
タスク 1 DynamoDB アンケート回答の保存先(GSI付き)
タスク 2 SNS メッセージのファンアウト(通知の分配)
タスク 3 SQS 非同期処理のためのメッセージキュー
タスク 4 SNS(フィルター) 評価1のみ管理者にメール通知
タスク 5 Lambda(受付) リクエスト受付とSNSへのパブリッシュ
タスク 6 Lambda(書き込み) SQSからメッセージを受信してDynamoDBに書き込み
タスク 7 API Gateway REST APIエンドポイントの提供
タスク 8 S3 静的アンケートフォームのホスティング
タスク 9 DynamoDB(GSI) 評価段階での効率的なデータ検索

このハンズオンで体験したサーバーレスアーキテクチャの特徴をまとめます。

  • サーバーの管理が不要で、コードとサービスの設定に集中できます。
  • SNSとSQSを組み合わせたファンアウトパターンで、1つのイベントから複数の処理を並列実行できます。
  • SQSキューを挟むことで、処理の失敗時にリトライが可能な疎結合設計になっています。
  • SNSのサブスクリプションフィルターで、条件に合致するメッセージだけを特定のエンドポイントに配信できます。
  • DynamoDBのGSIを使うことで、プライマリキー以外の属性でも効率的な検索が可能です。

最後までお読みいただきましてありがとうございました!

「AWS認定資格試験テキスト&問題集 AWS認定ソリューションアーキテクト - プロフェッショナル 改訂第2版」という本を書きました。

「AWS認定資格試験テキスト AWS認定クラウドプラクティショナー 改訂第3版」という本を書きました。

「AWS認定資格試験テキスト AWS認定AIプラクティショナー」という本を書きました。

「ポケットスタディ AWS認定 デベロッパーアソシエイト [DVA-C02対応] 」という本を書きました。

「要点整理から攻略するAWS認定ソリューションアーキテクト-アソシエイト」という本を書きました。

「AWSではじめるLinux入門ガイド」という本を書きました。

 - AWS , , , , , , ,

  関連記事

php-fpm で Out of memoryが発生した際にメール通知する(AWS CloudWatch , Amazon SNS)

AWS CloudWatch LogsエージェントでAmazon EC2上のNg …

EC2インスタンスを必要最小限のパラメータでCLIとSDKから起動する

EC2インスタンスをCLIとSDKから起動するデモで、パラメータを必要最小限にし …

EC2 Ubuntu DesktopにRDP

Ubuntu Desktopが必要になりましたので、こちらのAWS EC2でデス …

AWS Service Catalogポートフォリオを他のアカウントと共有する

AWS Service Catalogチュートリアルで作成したポートフォリオの他 …

Apple Silicon M1 MacBook ProにAWS CLI v2をインストール

公式手順どおりにインストールしました。 macOS での AWS CLI バージ …

WordPressのwp-login.php , xmlrpc.phpへのアクセスをAWS WAFで接続元IPアドレスを制限する

AWS CloudWatch LogsエージェントでAmazon EC2上のNg …

静的と動的って何ですか?と営業さんに聞かれたので端的に説明してみました

AWS認定クラウドプラクティショナーの勉強をしている営業さんに、「S3で静的オブ …

RDSスナップショットをS3にエクスポートする新機能を試そうかと思った

やったこと RDSスナップショットをS3にエクスポートできる、という新機能が追加 …

AWS CDKでクロススタックリファレンスをする

CloudFormationで複数のスタックで参照することがあります。 それをC …

VPN接続先のADで管理されているドメインにEC2 Windowsインスタンスから参加する

オンプレミスに見立てたオハイオリージョンにVyOSインスタンスを起動して東京リー …