2026年版「基本的なウェブアプリケーションを構築する」のチュートリアル手順作ってみた
必見の記事

2026年版「基本的なウェブアプリケーションを構築する」のチュートリアル手順作ってみた

初めてAWSのサーバレスサービスを学習するときに利用できる「基本的なェブアプリケーションを構築する」の内容を2026年現在でも実行できる手順にしてみました
2026.01.13

こんにちは、臼田です。

みなさん、AWSのハンズオンで学習してますか?(挨拶

今回は長らくAWSでサーバレスの入門編として活躍していた、AWS初心者向けハンズオンコンテンツである「基本的なウェブアプリケーションを構築する」がリニューアルされ以前のようにGUIベースで簡単に使えなくなってしまったので、旧来の手順を2026年版として起こします。以前は下記手順のようにAWSの提供するコンテンツと併用する手順を作っていましたが、本記事のみでサーバレスの入門として成り立つように編集しました。

https://dev.classmethod.jp/articles/2024-build-web-app-s3-lambda-api-gateway-dynamodb/

概要

AWSでは「サーバレス」と呼ばれる領域のサービス群やこれらを組み合わせて作成する「サーバレスアーキテクチャ」を実現することができます。しかしこの概念は説明を読んでも理解が簡単ではないかもしれません。

ということで実際にAWSのサーバレスサービスを活用して、サーバレスアーキテクチャで基本的なWebアプリケーションを構築してみよう、というのがこのハンズオンコンテンツです。

このコンテンツから入ってもいいですが、その前にAmazon EC2やAmazon RDSなどいわゆるVPC系のサービスを触ってからこのコンテンツを実施すると、より違いが実感できてサーバレスのメリットを感じられるでしょう。

手順

ではやっていきましょう。

はじめに

このチュートリアルでは以下の構成でウェブアプリケーションを作成します。最初は各構成要素についてよくわからないと思いますが、触っていくうちに少しずつ分かるので気にしなくて大丈夫です。

001_basic_web_app_2026

今回利用していくサービスを簡単に説明します。

  • AWS Amplify: Webアプリなどを簡単にインターネット上にデプロイ・公開するサービス
  • Amazon API Gateway: APIの入口となるサービス
  • AWS Lambda: Python/Node.js/Javaなどの各種プログラミング言語で記述した関数を実行するサービス
  • Amazon DynamoDB: サーバレスで活用できるNoSQLのデータベースサービス
  • AWS Identity and Access Management(IAM): AWS環境でユーザーや権限などを管理しアクセスを制御するサービス

1つ1つサービスを触りながら理解していきましょう。

出来上がるアプリケーションは非常にシンプルなものなので、まずは怖がらず最後まで手順通り進めてみてください。

こういったサーバレスアプリケーションの設計パターンはこちらも参考になるので余裕があれば見ておきましょう。

以下の6つのモジュールで進んでいきます。

  • ウェブアプリケーションを作成する (5分): AWS Amplify コンソールを使用して、ウェブアプリケーションの静的リソースをデプロイします。
  • サーバーレス関数を構築する (5 分): AWS Lambda を使用してサーバーレス関数を構築します。
  • サーバーレス関数をウェブアプリケーションにリンクする (5 分): API Gateway を使用してサーバーレス関数をデプロイします。
  • データテーブルを作成する (10 分): Amazon DynamoDB テーブルにデータを保持します。
  • ウェブアプリケーションに対話性を追加する (5 分): ウェブアプリケーションを変更して API を呼び出します。
  • リソースをクリーンアップする (5 分): このチュートリアルで使用したリソースをクリーンアップします。

モジュール1: ウェブアプリケーションを作成する

このモジュールではAWS Amplifyを利用してウェブアプリケーションのフロントエンドを構築します。と言っても、簡単な静的ウェブサイトです。

まずは自身のPCなどローカル環境で適当なテキストエディタ(メモ帳しか使ってないよという人は、VSCodeを使ってみるのもいいかもしれません)を開いて以下のHTMLをコピペしてindex.htmlというファイル名で保存します。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
</head>

<body>
    Hello World
</body>

</html>

保存したら右クリック等からZIPファイルに圧縮します。この時、index.htmlが入っているフォルダごとではなく、index.htmlのファイル単体のみをZIPファイルに圧縮するようにしてください。

それではAWSマネジメントコンソールを開いて、Amplifyのコンソールを開きましょう。どのリージョンを利用してもいいですが、基本的には東京(ap-northeast-1)を使用行きましょう。今回私は東京リージョンで実施しています。AmplifyコンソールはAWSマネジメントコンソール上部の検索欄から「amplify」と入力して開くと手っ取り早いでしょう。

Amplifyコンソールを開くと以下のようになっています。「アプリケーションをデプロイ」を押します。

002_basic_web_app_2026

「Gitなしでデプロイ」を選択して「次へ」進みます。

003_basic_web_app_2026

ZIPファイルをドラッグアンドドロップするエリアがあるので、ファイルを選択するかドラッグアンドドロップで先程のindex.htmlをZIPで圧縮したファイルをアップして「保存してデプロイ」します。

004_basic_web_app_2026

少しするとデプロイが完了し、ドメインが発行されURLからアクセスできるようになります。この素早くアプリケーションをインターネット上にデプロイして利用できるようにしてくれるのがAmplifyのいいところです。

ではウェブアプリをテストするためにドメインをクリックしてブラウザで表示します。

005_basic_web_app_2026

「Hello World」が表示され、先程アップロードしたindex.htmlがデプロイされていることが確認できました。

006_basic_web_app_2026

AmplifyがHTMLファイルをアップロードしたら、ウェブサイトを配信するための残りの必要な作業は全部やってくれたということです。

モジュール 2: サーバーレス関数を構築する

このモジュールでは裏側で動作するプログラムを記述します。利用するサービスはAWS Lambdaです。今回の手順ではPythonを利用しています。従来プログラムをコンピューター上で動作させるためには、動かすためのサーバー/OS/ミドルウェアなどをセットアップして準備し管理していく必要がありました。AWS Lambdaはそれらの管理をすべてAWS側に任せて、実行したいプログラムだけを作れば動作するようにしてくれるサービスです。

まずはLambda関数を作成します。AWS Lambdaの実態(実際に作られるリソース)は関数(Function)と呼びます。

AWSマネジメントコンソールの検索欄から「lambda」と検索してAWS Lambdaのコンソールを開きましょう。「関数の作成」を開始します。

007_basic_web_app_2026

「一から作成」になっている状態で関数名にHelloWorldFunctionを入れてランタイムを「Python 3.14」にします。手順にある名前やパラメータなどは手動で入力すると間違いの元ですから、必ずコピーペーストしましょう。大文字・小文字なども間違えてはいけませんからね。

他の設定は変更せず「関数の作成」をします。

008_basic_web_app_2026

関数の作成後、以下のようなポップアップが出ることがありますが、出たら「Accept」をクリックしましょう。あまり気にしなくて良い内容です。

009_basic_web_app_2026

Lambda関数の詳細画面を少し下にスクロールすると「コードソース」でテンプレートのコードが書かれています。これを以下のコードをコピーしてすべて置き換えます。置き換えたら左側の「Deploy」ボタンを押します。

# import the JSON utility package since we will be working with a JSON object
import json
# define the handler function that the Lambda service will use as an entry point
def lambda_handler(event, context):
# extract values from the event object we got from the Lambda service
    name = event['firstName'] +' '+ event['lastName']
# return a properly formatted JSON object
    return {
    'statusCode': 200,
    'body': json.dumps('Hello from Lambda, ' + name)
    }

010_basic_web_app_2026

デプロイできたらテストを実行していきます。Lambdaのコンソール上ではテストを作成開始する方法が2つありますが、今回は上部の「テスト」タブを開いてテストを作成します。イベント名にHelloWorldTestEvent、イベントJSONに以下のJSONオブジェクトを貼り付け、「保存」します。

{
    "firstName": "Ada",
    "lastName": "Lovelace"
}

011_basic_web_app_2026

保存できたら隣の「テスト」ボタンを押します。するとその上側に実行した結果が表示され、枠が緑色なら正常に完了しています。「詳細」をクリックして開き、ステータスコードが200になっていることと、bodyのメッセージ内容を確認します。

012_basic_web_app_2026

アプリケーションコードを実行する環境が自動的に作成され、言語を記述するだけで利用することができました。

モジュール 3: サーバーレス関数をウェブアプリケーションにリンクする

アプリケーションコードを実装しましたが、これだけだとインターネット上からアプリケーションを実行できません。インターネットからリクエストを受け付けるためにAPI Gatewayを作成します。

API Gatewayのコンソールも検索欄から探して開きましょう。「APIの作成」ボタンから作成を開始していきます。

013_basic_web_app_2026

いくつかのAPIの種類が選択できますが、REST APIを「構築」します。すぐ下に似た名前の「REST API プライベート」があるので間違えないようにしましょう。

014_basic_web_app_2026

「新しいAPI」が選択されていることを確認しつつ、API名にHelloWorldAPIを入力し、APIエンドポイントタイプで「エッジ最適化」を選択して「APIを作成」します。

015_basic_web_app_2026

APIが作成できたらメソッドを作成します。リソースページの左カラムで「/」が青く選択されていることを確認し、右下「メソッドを作成」します。

016_basic_web_app_2026

メソッドタイプ「POST」を選択し、統合タイプに「Lambda関数」が選択されていることを確認します。Lambda関数を選択するテキストボックスにHelloWorldFunctionを入力すると、先ほど作成した関数が表示されますのでこれを選択します。下の方に行き保存します。

017_basic_web_app_2026

保存できたらCORSの設定を行います。リソースページの左カラム「/」を選択して戻り、右側の「CORSを有効にする」を押します。

018_basic_web_app_2026

「POST」にチェックを入れて「保存」します。

019_basic_web_app_2026

設定できたので「APIをデプロイ」します。

020_basic_web_app_2026

API Gatewayでは複数のステージを作成して、開発中の環境と本番に展開する環境を分けるなど、開発に便利な使い方ができます。今回は最初なのでステージで「新しいステージ」を選択し、ステージ名をdevと入力して「デプロイ」します。

021_basic_web_app_2026

デプロイが完了したら、後でアプリケーションに組み込むためにステージのURLをコピーボタンを押して適当な場所にメモとして残しておきます。

022_basic_web_app_2026

デプロイしたAPIをテストします。左カラム「リソース」からリソースページに戻ってきて、POSTメソッドを開きます。

023_basic_web_app_2026

下の「テスト」タブを開き、リクエスト本文に以下のJSONオブジェクトをコピーして貼り付け「テスト」します。

{
    "firstName": "Grace",
    "lastName": "Hopper"
}

024_basic_web_app_2026

テストに成功すると、ステータスが200になり、先程Lambda関数単体で実行した結果と同じように、今度はGrace Hopperとして処理されます。

025_basic_web_app_2026

これでインターネットからAPI Gatewayを通してLambda関数のアプリケーションコードを実行できるようになりました。

モジュール 4: データテーブルを作成する

アプリケーションで実行した処理の結果などはデータベースに保存して活用したいです。AWSのサーバレスアプリケーションではDynamoDBを利用することで簡単にNoSQLデータベースを組み込むことができます。

AWSマネジメントコンソール上でDynamoDBのコンソールを検索して開きます。「テーブルを作成」開始します。

026_basic_web_app_2026

テーブル名にHelloWorldDatabaseを、パーティションキーにIDを入力します。ここも必ず入力する内容はこの手順からコピーペーストしましょう。間違えてidのように小文字で入力してしまうと、この先の手順でエラーとなります。下の方に行き「テーブルの作成」をします。

027_basic_web_app_2026

作成して少しすると、テーブル名をクリックして詳細画面を表示できるようになります。開きましょう。

028_basic_web_app_2026

詳細画面で「設定」タブの「一般的な情報」の下の方にAmazonリソースネーム(ARN)を確認できるので左のコピーボタンを押して、メモしておきます。

029_basic_web_app_2026

テーブルが作成できたら、Lambda関数からテーブルにデータを保存できるようにします。AWSのリソースはデフォルトではリソース間のやりとりは許可されていません。そのため、Lambda関数からDynamoDBのテーブルへのアクセスを許可する設定をしていきます。ちなみにAPI GatewayとLambda関数の間の設定は、先程の手順の中で自動的に設定されていました。

Lambda関数の画面に戻り、「設定」タブの「アクセス権限」カラムを開き、実行ロールと書かれている部分のIAM Role名のリンクをクリックします。

030_basic_web_app_2026

すると、Lambda関数を作成するときに一緒に自動作成されたIAM Roleが開きます。Lambda関数に権限を与えるときは、各Lambda関数にアタッチするIAM Roleに権限を与えていきます。許可ポリシーで「許可を追加 -> インラインポリシーを作成」します。

031_basic_web_app_2026

ポリシーエディタで「JSON」での入力に切り替えて以下のJSONオブジェクトをコピペします。15行目の「YOUR_TABLE_ARN」となっている部分を、書き込み先のDynamoDBのARNに置き換えます。両隣のダブルクォーテーション(")などを消さないように気をつけて置き換えたら「次へ」進みます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem",
                "dynamodb:DeleteItem",
                "dynamodb:GetItem",
                "dynamodb:Scan",
                "dynamodb:Query",
                "dynamodb:UpdateItem"
            ],
            "Resource": "YOUR_TABLE_ARN"
        }
    ]
}

032_basic_web_app_2026

ポリシー名にHelloWorldDynamoPolicyを入力して「ポリシーの作成」をします。

033_basic_web_app_2026

作成できたらアプリケーションコードをDynamoDBと連携するものに変更します。Lambda関数の画面に戻り「コード」タブを開き、以下のコードをコピーして、すべて置き換えます。「Deploy」しましょう。

# import the json utility package since we will be working with a JSON object
import json
# import the AWS SDK (for Python the package name is boto3)
import boto3
# import two packages to help us with dates and date formatting
from time import gmtime, strftime

# create a DynamoDB object using the AWS SDK
dynamodb = boto3.resource('dynamodb')
# use the DynamoDB object to select our table
table = dynamodb.Table('HelloWorldDatabase')
# store the current time in a human readable format in a variable
now = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())

# define the handler function that the Lambda service will use as an entry point
def lambda_handler(event, context):
# extract values from the event object we got from the Lambda service and store in a variable
    name = event['firstName'] +' '+ event['lastName']
# write name and time to the DynamoDB table using the object we instantiated and save response in a variable
    response = table.put_item(
        Item={
            'ID': name,
            'LatestGreetingTime':now
            })
# return a properly formatted JSON object
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda, ' + name)
    }

気になる人はコードの中身も読んでみましょう。

034_basic_web_app_2026

「テスト」タブに切り替えて「テスト」します。先ほどと同じように緑になり200のステータスになればOKです。

035_basic_web_app_2026

今度はDynamoDBテーブルにも書き込みができているはずなので確認します。テーブルの詳細画面に戻り、右上の「テーブルアイテムの探索」を押します。

036_basic_web_app_2026

下の方にテーブルに保存されたデータが表示されます。Lambda関数のテストで入力した「Ada Lovelace」が表示されたらOKです。

037_basic_web_app_2026

これでLambda関数で実行した内容がDynamoDBテーブルに保存されるようになりました。

モジュール 5: ウェブアプリケーションに対話性を追加する

最後に、Amplifyで配信したフロントエンドをAPI Gatewayから始まるバックエンドに接続して完成です。

ローカル環境でindex.hemlを以下のコードに置き換えます。45行目の「YOUR_API_INVOKE_URL」は先ほど控えたAPI GatewayのステージのURLに置き換えましょう。前後のダブルクォーテーションやその他の処理を消さないように気をつけましょう。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
    <!-- Add some CSS to change client UI -->
    <style>
        body {
            background-color: #232F3E;
        }

        label,
        button {
            color: #FF9900;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 20px;
            margin-left: 40px;
        }

        input {
            color: #232F3E;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 20px;
            margin-left: 20px;
        }
    </style>
    <script>
        // define the callAPI function that takes a first name and last name as parameters
        var callAPI = (firstName, lastName) => {
            // instantiate a headers object
            var myHeaders = new Headers();
            // add content type header to object
            myHeaders.append("Content-Type", "application/json");
            // using built in JSON utility package turn object to string and store in a variable
            var raw = JSON.stringify({ "firstName": firstName, "lastName": lastName });
            // create a JSON object with parameters for API call and store in a variable
            var requestOptions = {
                method: 'POST',
                headers: myHeaders,
                body: raw,
                redirect: 'follow'
            };
            // make API call with parameters and use promises to get response
            fetch("YOUR_API_INVOKE_URL", requestOptions)
                .then(response => response.text())
                .then(result => alert(JSON.parse(result).body))
                .catch(error => console.log('error', error));
        }
    </script>
</head>

<body>
    <form>
        <label>First Name :</label>
        <input type="text" id="fName">
        <label>Last Name :</label>
        <input type="text" id="lName">
        <!-- set button onClick method to call function we defined passing input values as parameters -->
        <button type="button"
            onclick="callAPI(document.getElementById('fName').value,document.getElementById('lName').value)">Call
            API</button>
    </form>
</body>

</html>

置き換えたら、先程と同じ手順で保存しZIPにして、Amplifyにデプロイします。Amplifyコンソールで「アップデートをデプロイ」します。

038_basic_web_app_2026

ドラッグアンドドロップでZIPをアップロードし「保存してデプロイ」します。

039_basic_web_app_2026

少しするとデプロイが完了するので、ブラウザでドメインを開きます。

すると先ほどと違って更新したHTMLが表示されます。適当な名前を入力して「Call API」を実行しましょう。

040_basic_web_app_2026

実行した結果のレスポンスがポップアップされます。テストと同じように名前に入力した内容を含むメッセージが出力されました。

データベース側も確認してみます。DynamoDBの「テーブルアイテムの探索」画面で更新ボタンを押すと、フロント側で入力した名前が保存されていることが確認できました。

041_basic_web_app_2026

適切にフロントエンドからバックエンドまで一通り繋げて、1つのウェブアプリケーションとして構築できました。

モジュール 6: リソースをクリーンアップする

作ったら消すまでがチュートリアルです。ほとんど無料枠で完結するはずですが、終了したら速やかに削除しましょう。またすぐに構築できますからね。

DynamoDBはテーブル一覧の画面からチェックを入れ「削除」します。

042_basic_web_app_2026

確認画面では一緒に作成されたアラームの削除にチェックが入っていて、バックアップ作成はチェックが外れている状態のはずです。そのままにして「確認」と入力し「削除」します。

043_basic_web_app_2026

API Gatewayは右上「APIアクション -> APIを削除」から実行します。

044_basic_web_app_2026

「確認」を入力して「削除」します。

045_basic_web_app_2026

Lambda関数は右上「アクション -> 関数の削除」から実行します。

046_basic_web_app_2026

「確認」を入力して「削除」します。

047_basic_web_app_2026

Lambda関数にアタッチしていたIAM Roleは詳細画面右上「削除」から実行します。

048_basic_web_app_2026

確認がでるのでIAM Role名を貼り付けて「削除」します。

049_basic_web_app_2026

Amplifyアプリケーションは「アプリケーションの設定 -> 全般設定」の右下で「アプリの削除」します。

050_basic_web_app_2026

フィールドに「削除」と入力し「アプリの削除」します。

051_basic_web_app_2026

以上で一通り作成したリソースの削除が完了です。

まとめ

AWSのサーバレスサービスを利用して基本的なウェブアプリケーションを構築するチュートリアルを行いました。

EC2やRDSなど自分で必要なリソースを作成して設定をしていく手法も良いですが、サーバレスなサービスを使えばより簡単にAWSにいろいろなものを任せて仕組みを作ることができます。

この利便性を体験し、やりたいことを実現する手段を身につけましょう。

この記事をシェアする

FacebookHatena blogX

関連記事