ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【サーバーレス入門】サーバー構築不要なWEBサイトを作ってみる

この記事を共有する

目次

はじめに

パーソル&サーバーワークス サービスGの細井です。
生成AIの登場により、「こんなアプリを作りたい」と思ったら、AIと対話しながらコードを形にできる時代になりました。プログラミングのハードルはかつてないほど下がっています。
しかし、いざ作ったアプリケーションを公開するには、サーバーの構築、OS の設定、ミドルウェアのインストールなど インフラの管理 が必要です。
コードは書けたのに、動かす環境を用意するのが大変」という経験をされた方も多いのではないでしょうか。
そこでこの記事では、AWS初学者・インフラ初学者の方を対象に、サーバーレス構成でひとこと掲示板を作るハンズオンをご紹介します。

サーバーレス構成とは?

「サーバーレス」という名前から「サーバーが要らない構成」と思ってしまいますが、実際にはサーバーは裏側で動いています。
それらサーバーの構築・管理・運用をすべてAWSが担当してくれるため、利用者はサーバーの存在を意識する必要がないのです。

例えばオンプレミス環境で Web システムを構築する場合、一般的に以下のような作業が必要です。

  1. ハードウェアの調達 -- サーバー機器の選定・発注・ラック搭載
  2. OS のインストールと設定 -- Linux / Windows のセットアップ、ネットワーク設定
  3. ミドルウェアの構築 -- インストールと設定作業
  4. アプリケーションのデプロイ -- コードの配置、動作確認
  5. 運用・保守 -- OS パッチ適用、障害対応、バックアップ、スケーリング

サーバーレス構成で利用者が主に意識するのは アプリケーションのデプロイ に絞ることができます。 料金体系も使った分だけの従量課金制のため、スモールスタートをさせたい場合にも導入しやすいサービスです。

今回作るもの

「ひとこと掲示板」 -- 名前とメッセージを投稿し、一覧表示できるシンプルな Web アプリケーションです。

シンプルな構成ですが、オンプレミスで同じものを作ろうとすると、
主に「Web/アプリケーションサーバー + データベースサーバー」の各サーバーの構築が必要になります。
今回はそれを サーバー管理が不要なサービスのみで作る サーバーレス構成 で実現します。

構成イメージ

サーバーレス_ハンズオン構成図.png

使用するAWSサービスの紹介

今回のハンズオンで使う5つのサービスを簡単に紹介します。

サービス名概要今回の用途
Amazon CloudFront AWSが提供するCDNサービス。
キャッシュによる高速配信に加え、HTTPS提供やリクエストの振り分けなど、Webアプリケーションの入口として機能。
リバースプロキシ
+ CDN
+ HTTPS終端
Amazon S3 容量無制限のオブジェクトストレージ。
HTMLや画像などの静的ファイルを格納し、
Webサイトとして公開可能。
Webサーバーのドキュメントルート
Amazon API Gateway APIエンドポイントを作成・管理するサービス。
受け取ったリクエストをLambdaなどのバックエンドに振り分ける。
APIの公開・管理基盤
AWS Lambda サーバー不要でコードを実行できるサービス。
リクエストが来たときだけ実行され、処理後は自動停止する。
アプリケーション
サーバー
Amazon DynamoDB サーバーレスなNoSQLデータベースサービス。
テーブルを作るだけで利用開始でき、
サーバー管理や接続数の管理などが不要。

データベース

前提条件

  • AWSアカウントが作成済みであり、AWS マネジメントコンソールにログインできること

本ハンズオンで発生する料金について

Lambda・CloudFront・DynamoDB には Always Free(常時無料枠) があり、その枠内であればアカウントの新旧を問わず毎月無料で利用できます。
本ハンズオン程度の利用量であれば、これらのサービスで課金が発生することはありません。

注意1: 無料利用枠を超過した場合は課金が発生します。ハンズオン終了後は必ず「クリーンアップ」セクションの手順でリソースを削除してください。

注意2: S3、API Gateway には常時無料枠がありませんが、今回のハンズオンで発生する利用量はごく少量のため、料金が発生したとしても数円程度で収まる想定です。

サービスAlways Free(常時無料枠)
Lambda100 万リクエスト/月、40 万 GB 秒/月
CloudFront1 TB/月 のデータ転送、1,000 万 HTTP/HTTPS リクエスト/月
DynamoDB25 GB ストレージ、25 WCU + 25 RCU(プロビジョンドモードのみ)
S3常時無料枠なし
API Gateway常時無料枠なし

ステップ 1:DynamoDB テーブルを作成する

最初に、メッセージを保存するデータベースを作成します。

1.AWS マネジメントコンソールにログインする
2.画面右上のリージョン選択で 「アジアパシフィック(東京)ap-northeast-1」 を選択する
DynamoDB<em>1-1.png
3.サービス検索バーに「DynamoDB」と入力し、DynamoDB を選択する
4.左側ナビゲーションペインから 「テーブル」 を選択する
DynamoDB</em>1-2.png
5.「テーブルの作成」 ボタンを選択する
以下の項目を設定します。

項目設定値
テーブル名serverless-handson-messages
パーティションキーid(文字列)

DynamoDB_1-3.png

パーティションキーとは?
DynamoDB でデータを一意に識別するためのキーです。RDBMS でいう「主キー(PRIMARY KEY)」に相当します。

6.「テーブル設定」「設定をカスタマイズ」 を選択する
7.「読み込み/書き込みキャパシティーの設定」 セクションで以下を設定する

項目設定値
キャパシティーモードプロビジョンド
読み込みキャパシティー - Auto Scalingオフ
読み込みキャパシティーユニット5
書き込みキャパシティー - Auto Scalingオフ
書き込みキャパシティーユニット5

DynamoDB<em>1-4.png
8.その他の設定はデフォルトのまま、「テーブルの作成」 ボタンを選択する
9.テーブルのステータスが 「アクティブ」 になるまで待つ(通常数秒〜1分程度) DynamoDB</em>1-5.png

ステップ 2:Lambda 関数を作成する

次に、API のリクエストを処理するアプリケーションロジックを作成します。

Lambda では コードを書いてアップロードするだけで、実行環境はAWSによって自動的に用意されます。サーバーの起動・停止やプロセス管理も一切不要です。さらに、リクエストが来たときだけ実行されるため、アイドル時のリソース消費もありません。

1.サービス検索バーに「Lambda」と入力し、Lambda を選択する
2.左側ナビゲーションペインから 「関数」 を選択する
3.「関数の作成」 ボタンを選択する
Lambda_1-1.png

以下の項目を設定します。

項目設定値
関数の作成方法一から作成
関数名serverless-handson-lambda
ランタイムPython 3.14


Lambda_1-2.png

Lambda関数実行ロールの設定
・カスタム設定の「その他の設定」を開く
・「カスタム実行ロール」を有効化する
・右側ペインにロールの設定画面が表示されるので、「新しいロールの作成」を選択
Lambda<em>1-3.png
・ロール名に「serverless-handson-lambda-role」を設定
・追加ポリシーにて、「既存のポリシーを使用」を選択
・検索バーに AmazonDynamoDBFullAccess_v2 と入力
AmazonDynamoDBFullAccess_v2のポリシーにチェックを入れてから、「ロールを作成」を押下
Lambda</em>1-4.png
・右ペインにてロールが正常に作成された旨のメッセージが表示されていれば、「保存」を押下
Lambda_1-5.png

注意: このハンズオンでは簡略化のために AmazonDynamoDBFullAccess_v2 を使用しています。本番環境では、対象テーブルへの必要最小限の権限のみを付与するカスタムポリシーを作成してください。

4.「関数の作成」 ボタンを選択する
Lambda_1-6.png

2-1. Lambda 関数のコードを編集する

関数が作成されたら、コードエディターが表示されます。

1.「コード」 タブを選択する
2.lambda_function.py の内容をすべて削除し、以下のコードに置き換える

lambda_function.py(ここを押すと展開します)


import json      # JSON データを扱うためのライブラリ
import boto3     # AWS のサービスを Python から操作するためのライブラリ
import uuid      # ユニーク(一意)な ID を生成するためのライブラリ
# ----- 初期設定 -----
# DynamoDB テーブルに接続する(テーブル名はステップ 1 で作成したもの)
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('serverless-handson-messages')
def lambda_handler(event, context):
    """
    この関数が Lambda のエントリーポイント(実行開始地点)です。
    API Gateway からリクエストが届くと、この関数が自動的に呼び出されます。
    処理の流れ:
      1. リクエストの種類(GET or POST)を判定する
      2. GET → メッセージ一覧を返す
      3. POST → 新しいメッセージを保存する
    """
    # --- 共通のレスポンスヘッダー ---
    headers = {
        'Content-Type': 'application/json'
    }
    # リクエストの種類を取得する(GET / POST)
    # HTTP API(ペイロード形式 v2.0)では requestContext.http.method から取得する
    method = event['requestContext']['http']['method']
    # ----- GET: メッセージ一覧を取得する -----
    if method == 'GET':
        # DynamoDB からすべてのメッセージを取得する
        result = table.scan()
        messages = result['Items']
        # レスポンスを返す
        return {
            'statusCode': 200,
            'headers': headers,
            'body': json.dumps(messages, ensure_ascii=False)
        }
    # ----- POST: 新しいメッセージを保存する -----
    elif method == 'POST':
        # リクエストの本文(body)を読み取る
        body = json.loads(event['body'])
        # DynamoDB に保存するデータを組み立てる
        item = {
            'id': str(uuid.uuid4()),       # ランダムな一意の ID
            'name': body.get('name', '名無し'),  # 名前(未入力なら「名無し」)
            'message': body['message']      # メッセージ本文
        }
        # DynamoDB にデータを書き込む
        table.put_item(Item=item)
        # 保存したデータをそのまま返す
        return {
            'statusCode': 200,
            'headers': headers,
            'body': json.dumps(item, ensure_ascii=False)
        }
    # ----- その他のリクエスト -----
    else:
        return {
            'statusCode': 400,
            'headers': headers,
            'body': json.dumps({'error': '不正なリクエストです'}, ensure_ascii=False)
        }

Lambda<em>1-7</em>2.png

3.「Deploy」 ボタンを選択してコードをデプロイする Lambda_1-8.png

ステップ 3:API Gateway を作成する

Lambda 関数を HTTP でアクセスできるようにするために、API Gateway を設定します。

1.サービス検索バーに「API Gateway」と入力し、API Gateway を選択する
2.「API を作成」 ボタンを選択する
APIGateway<em>1-1.png
3.「HTTP API」「構築」 ボタンを選択する
APIGateway</em>1-2.png

API キー、リソースポリシー、AWS WAF、プライベートエンドポイントなどの高度な機能が必要な場合は REST API を選択します
(詳細は以下リンクにて詳しくまとめられています)
Choose between REST APIs and HTTP APIs

3-1. 統合と API 名を設定する

1.「統合を追加」 を選択する

項目設定値
統合Lambda
AWS リージョンap-northeast-1
Lambda 関数serverless-handson-lambda
バージョン2.0(デフォルト)

2.API 名を入力する

項目設定値
API 名serverless-handson-api

3.「次へ」 を選択する
APIGateway_1-3.png

3-2. ルートを設定する

1.以下のルートを追加する(+ ボタンで行を追加)

メソッドリソースパス統合ターゲット
GET/api/messagesserverless-handson-lambda
POST/api/messagesserverless-handson-lambda

2.「次へ」 を選択する
APIGateway_1-4.png

3-3. ステージを設定する

項目設定値
ステージ名handson
自動デプロイオン(デフォルト)
  1. 「次へ」 を選択する
    APIGateway_1-5.png

  2. 設定内容を確認し、「作成」 を選択する
    APIGateway_1-6.png

3-4. エンドポイント URL をメモする

作成された API の詳細画面に、以下のような 呼び出し URL が表示されます。

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

実際の API エンドポイントは以下の形式になります(ステージ名 + ルートパス)。

https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/handson/api/messages

APIGateway_1-7.png

3-5. API の動作確認(オプション)

ブラウザーで以下の URL にアクセスして、API が正常に動作するか確認します。

https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/handson/api/messages

空の配列 [] が返ってくれば成功です(まだメッセージが投稿されていないため)

APIGateway_1-8.png

ステップ 4:S3 バケットを作成し、静的ファイルをアップロードする

Web サイトの HTML / CSS / JavaScript ファイルを格納する S3 バケットを作成します。

S3 では、バケットを作成してそこにファイルをアップロードするだけで
静的Webホスティングが可能です。

1.サービス検索バーに「S3」と入力し、S3 を選択する
2.「バケットを作成」 ボタンを選択する
S3_1-1.png

以下の項目を設定します。

項目設定値
バケットタイプアカウントのリージョナル名前空間
バケット名serverless-handson-site
AWS リージョンアジアパシフィック(東京)ap-northeast-1

S3_1-2.png

アカウントのリージョナル名前空間とは
バケット名はグローバルで一意の名前を与える必要がありますが、自分のアカウントだけに予約された名前空間を使ってバケットを作成することもできます。
入力したバケット名の末尾に -<アカウントID>-<リージョン>-an というサフィックスが自動付与されるため、一意であるバケット名を考える必要がありません
今回のバケットでは 「serverless-handson-site-<アカウントID>-ap-northeast-1-an」 となります。

3.その他の設定はデフォルトのまま、「バケットを作成」 ボタンを選択する
※パブリックアクセスのブロックは全てONにしたまま進む S3<em>1-3.png
S3</em>1-4.png

4-1. HTML ファイルを作成してアップロードする

ローカル PC で以下の HTML ファイルを作成します。

ファイル名: index.html

index.html(ここを押すと展開します)


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ひとこと掲示板 - サーバーレスハンズオン</title>
    <style>
        body {
            font-family: sans-serif;
            max-width: 700px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        h1 {
            background-color: #232f3e;
            color: white;
            padding: 15px;
            text-align: center;
            border-radius: 8px;
        }
        .form-area {
            background: white;
            padding: 20px;
            margin: 20px 0;
            border-radius: 8px;
            border: 1px solid #ddd;
        }
        input, textarea {
            width: 100%;
            padding: 8px;
            margin: 5px 0 15px 0;
            border: 1px solid #ccc;
            border-radius: 4px;
            font-size: 16px;
        }
        textarea { height: 80px; }
        button {
            background-color: #ff9900;
            color: white;
            border: none;
            padding: 10px 25px;
            font-size: 16px;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover { background-color: #ec7211; }
        .message {
            background: white;
            padding: 15px;
            margin: 10px 0;
            border-radius: 8px;
            border: 1px solid #ddd;
        }
        .message .name { font-weight: bold; color: #232f3e; }
        .info {
            background-color: #e8f5e9;
            border: 1px solid #c8e6c9;
            padding: 15px;
            border-radius: 8px;
            margin: 20px 0;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <h1>ひとこと掲示板</h1>
    <div class="info">
        <strong>この Web サイトの構成:</strong><br>
        CloudFront → S3(この HTML)→ API Gateway → Lambda → DynamoDB<br>
        サーバーは一台も使っていません。すべて AWS のマネージドサービスで動いています。
    </div>
    <div class="form-area">
        <h2>メッセージを投稿</h2>
        <label for="name">名前</label>
        <input type="text" id="name" placeholder="名前を入力(省略可)">
        <label for="message">メッセージ</label>
        <textarea id="message" placeholder="メッセージを入力してください"></textarea>
        <button onclick="postMessage()">投稿する</button>
    </div>
    <h2>みんなのメッセージ</h2>
    <div id="messageList">読み込み中...</div>
    <script>
        // CloudFront 経由でアクセスするため、同じドメインの相対パスを指定する
        var API_URL = '/api/messages';
        loadMessages();
        function loadMessages() {
            fetch(API_URL)
                .then(function (response) {
                    if (!response.ok) { throw new Error('API エラー: ' + response.status); }
                    return response.json();
                })
                .then(function (messages) {
                    var area = document.getElementById('messageList');
                    if (messages.length === 0) {
                        area.innerHTML = '<p style="color:#888;">まだメッセージがありません。最初の投稿をしてみましょう!</p>';
                        return;
                    }
                    var html = '';
                    for (var i = 0; i < messages.length; i++) {
                        html = html
                            + '<div class="message">'
                            + '  <span class="name">' + messages[i].name + '</span><br>'
                            + '  ' + messages[i].message
                            + '</div>';
                    }
                    area.innerHTML = html;
                })
                .catch(function () {
                    document.getElementById('messageList').innerHTML
                        = '<p style="color:red;">読み込みに失敗しました。CloudFront の設定を確認してください。</p>';
                });
        }
        function postMessage() {
            var name = document.getElementById('name').value || '名無し';
            var message = document.getElementById('message').value;
            if (!message) { alert('メッセージを入力してください。'); return; }
            fetch(API_URL, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ name: name, message: message })
            })
            .then(function (response) {
                if (!response.ok) { throw new Error('API エラー: ' + response.status); }
                document.getElementById('name').value = '';
                document.getElementById('message').value = '';
                loadMessages();
            })
            .catch(function () { alert('投稿に失敗しました。CloudFront の設定を確認してください。'); });
        }
    </script>
</body>
</html>

4-2. ファイルを S3 にアップロードする

1.S3 コンソールで作成したバケット(serverless-handson-site-<アカウントID>-ap-northeast-1-an)を選択する
2.「アップロード」 ボタンを選択する
S3<em>1-5</em>2.png
3.「ファイルを追加」 を選択し、作成した index.html を選択する
4.「アップロード」 ボタンを選択する
S3_1-6.png

ステップ 5:CloudFront ディストリビューションを作成する

S3 に配置した Web サイトを、CloudFront(CDN)経由で安全に配信します。

1.サービス検索バーに「CloudFront」と入力し、CloudFront を選択する
2.「ディストリビューションを作成」 ボタンを選択する
CloudFront_1-1.png

5-1. 料金プランの選択

1.Pay as you go(従量課金)を選択する
CloudFront_1-2.png

料金プランについて
Pay as you go(従量課金)では、常時無料枠(1 TB/月、1,000 万リクエスト/月)が適用されます。
今回のハンズオンでは無料枠で収まるため、Pay as you go を選択します。

5-2. ディストリビューションの基本設定

以下の通り設定します。

項目設定値
Distribution name空欄のまま(任意。入力する場合は serverless-handson など)
Description空欄のまま
Distribution typeSingle website or app を選択
Route 53 managed domain空欄のまま(今回は独自ドメインを使用しないため)

CloudFront_1-3.png

  1. 画面下部の 「Next」 または設定を進めて、オリジンの設定画面に移動する

5-3. オリジンの選択と設定

S3 バケットをオリジン(配信元)として指定します。

  1. 「Origin domain」 のドロップダウンから、作成した S3 バケットを選択する

S3 バケットを選択すると、以下の設定項目が表示されます。

項目設定値
Origin path(オリジンパス)空欄のまま
Allow private S3 bucket access to CloudFrontAllow private S3 bucket access to CloudFront - Recommended を選択(デフォルト)
Origin settingsUse recommended origin settings を選択(デフォルト)
Cache settingsUse recommended cache settings tailored to serving S3 content を選択(デフォルト)
  1. すべてデフォルト(推奨設定)のまま、次へ進む
    CloudFront_1-4.png

5-4. Web Application Firewall (WAF)

以下の通り進めていきます。

項目設定値
WAFセキュリティ保護を有効にしないでください

CloudFront_1-5.png

注意: このハンズオンではコスト削減のために WAF を無効にしています。

5-5. デプロイ完了を待つ

1.確認画面にて、ディストリビューション作成ボタンを押下します。
CloudFront<em>1-6</em>2.png
2.作成したディストリビューションのステータスが 「有効」 になるまで待つ(通常 3〜5 分程度)
3.「ディストリビューションドメイン名」 をメモする

例: d1234567890abc.cloudfront.net

5-6. デフォルトルートオブジェクトの設定

1.作成したディストリビューションを開き、一般タブから編集ボタンを押下します
CloudFront<em>1-7</em>2.png
2.以下の通り設定を変更して保存します。

項目設定値
デフォルトルートオブジェクトindex.html

CloudFront_1-8.png

補足: Apache での DirectoryIndex index.html の設定に相当します。
URL のパスを省略してアクセスしたときに、自動的に index.html を返すようにする設定です。

5-7. API Gateway をオリジンとして追加する

CloudFront に API Gateway を2つ目のオリジンとして追加し、/api/* へのアクセスを API Gateway にルーティングします。

1.作成したディストリビューションを選択する
2.「オリジン」 タブを選択する
3.「オリジンを作成」 ボタンを選択する
CloudFront_1-9.png
4.以下設定の通り進めていきます。

項目設定値
オリジンドメインステップ 3-4 でメモした API Gateway の URL からドメイン部分を入力(例: xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com
プロトコルHTTPS のみ
オリジンパス/handson(ステップ 3-4 で作成したステージ名)

注意: オリジンドメインには https:// やステージ名(/handson)を含めないでください。
ステージ名はオリジンパスに設定します。

5.その他の設定はデフォルトのまま、「オリジンを作成」 ボタンを選択する
CloudFront_1-10.png

5-8. API 用のビヘイビアを作成する

1.「ビヘイビア」 タブを選択する
2.「ビヘイビアを作成」 ボタンを選択する
CloudFront_1-11.png
3.以下設定の通り進めていきます。

項目設定値
パスパターン/api/*
オリジンとオリジングループ上で作成した API Gateway のオリジンを選択
ビューワープロトコルポリシーRedirect HTTP to HTTPS
許可される HTTP メソッドGET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE

4.「キャッシュキーとオリジンリクエスト」 セクションで以下を設定する

項目設定値
キャッシュポリシーCachingDisabled
オリジンリクエストポリシーAllViewerExceptHostHeader

CloudFront_1-12.png

ポイント: API へのリクエストはキャッシュしてはいけないため、CachingDisabled を選択します。
AllViewerExceptHostHeader は、ブラウザーからのリクエスト情報(ヘッダーやクエリ文字列)を API Gateway にそのまま転送するための設定です。

5.その他の設定はデフォルトのまま、「ビヘイビアを作成」 ボタンを選択する
6.CloudFront の再デプロイが完了するまで待つ(通常 3〜5 分程度)

ポイント: CloudFront が S3 と API Gateway の両方の前段に入ることで、ブラウザーからは単一のドメイン(https://d1234567890abc.cloudfront.net)ですべてにアクセスできます。

ステップ 6:動作確認

すべての設定が完了しました。Web サイトにアクセスして動作を確認します。

1.ブラウザーで作成したディストリビューション名の URL(dxxxxxxxxxxxxx.cloudfront.net) にアクセスする

https://dxxxxxxxxxxxxx.cloudfront.net

dxxxxxxxxxxxxx.cloudfront.net の部分は、ステップ 5-5 でメモした自分のディストリビューションドメイン名に置き換えてください。

2.「ひとこと掲示板」のページが表示されることを確認する
page1-1.png
3. 名前とメッセージを入力して 「投稿する」 ボタンを選択する
4. 投稿したメッセージが一覧に表示されることを確認する
5. ページをリロードしても、投稿したメッセージが保持されていることを確認する
page1-2.png

クリーンアップ(ハンズオン終了後)

ハンズオン終了後、不要なリソースを削除して課金を防ぎます。

1. CloudFront ディストリビューションの削除

CloudFront は削除前に「無効化」が必要です。

  1. CloudFront コンソールを開く
  2. 作成したディストリビューションを選択する
  3. 「無効にする」 ボタンを選択する
  4. ステータスが 「無効」 になるまで待つ(数分かかります)
  5. 再度ディストリビューションを選択し、「削除」 ボタンを選択する

2. S3 バケットの削除

  1. S3 コンソールを開く
  2. 「serverless-handson-site-<アカウントID>-ap-northeast-1-an」 バケットを選択する
  3. 「空にする」 を選択し、バケット内のオブジェクトをすべて削除する
  4. バケットを選択し、「削除」 を選択する

3. API Gateway の削除

  1. API Gateway コンソールを開く
  2. 左側ナビゲーションの 「API」 を選択
  3. 「serverless-handson-api」 を選択して、「削除」 を押下する
  4. 確認ダイアログで API 名を入力して削除する

4. Lambda 関数の削除

  1. Lambda コンソールを開く
  2. 左側ナビゲーションの 「関数」 を選択
  3. 「serverless-handson-lambda」 関数を選択して、「アクション」「関数の削除」 を押下する

5. DynamoDB テーブルの削除

  1. DynamoDB コンソールを開く
  2. 左側ナビゲーションの 「テーブル」 を選択
  3. 「serverless-handson-messages」 テーブルを選択して、「削除」 ボタンを選択する
  4. 確認ダイアログでチェックボックスはデフォルトのまま、「確認」と入力して削除する

6. IAM ロールの削除(オプション)

  1. IAM コンソールを開く
  2. 左側ナビゲーションから 「ロール」 を選択する
  3. 「serverless-handson-lambda-role」 のロールを検索して選択する
  4. 「削除」 ボタンを選択する

7. CloudWatch Logs の削除(オプション)

  1. CloudWatch コンソールを開く
  2. 左側ナビゲーションから 「ログ管理」 を選択する
  3. 「/aws/lambda/serverless-handson-lambda」 ロググループを選択する
  4. 「アクション」「ロググループの削除」 を選択する

補足

API Gateway へのアクセス制御

今回の構成では、API Gateway の URL(https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/handson/api/messages)に直接アクセスすると、CloudFront を経由せずに API を呼び出せてしまいます。
本番環境では API Gateway への直接アクセスを制限し、CloudFront 経由のみに限定することを推奨します。

AWS では「オリジンクローキング」と呼ばれる手法で、CloudFront 経由のアクセスのみを許可する構成が推奨されています。
例えば、CloudFrontにてカスタムヘッダーを付与して、それをAPI Gatewayで検証したり、前段にLambdaやAWS WAFを配置して検証させることで対策が可能です。

まとめ

今回のハンズオンはシンプルな構成でしたが、「必要なものを、必要なときに、必要な分だけ」 使えるサーバーレス構成は、クラウドならではの魅力だと思います。
日々変わっていく情報を追いながら構成や運用を考えるクラウドならではの難しさもありますが、それは楽しみでもあると感じています。
このハンズオンを通して、そんなAWSの魅力について感じていただけていたら幸いです。

この記事は私が書きました

T.Hosoi

記事一覧

2025年11月入社です。AWS資格の全冠目指して修行中です。 カレー屋巡りが趣味です。

T.Hosoi

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。