もちろん!AWSのS3とLambdaを使えばいいんだよ!
それ、それ!今回はAWS上で実際にWebアプリをホストしてみよう!
今回は、AWS の強力なサービスである S3 と Lambda を活用して、React アプリをホストする方法をご紹介します。
この記事では、環境準備からホスティングまでをステップバイステップで解説し、独自ドメインの設定や HTTPS の有効化までカバーします。
初心者でもわかりやすく実践できる内容なので、ぜひ最後までご覧ください!
このプロジェクトの完全なコードはGitHubリポジトリで公開しています。
以下のリンクからダウンロードしてください。
https://github.com/my-repo-441/aws-s3-lambda-example
Contents
環境準備
Viteを使ったReactアプリの作成
まず、Node.jsをインストールして、正しいバージョンが導入されていることを確認します。
私の環境は以下の通りです。
% node -v
v22.10.0
その後、Viteを使ってReactアプリを以下の手順で作成します。
- Viteプロジェクトを作成します。
% npm create vite@latest my-app -- --template react
- 作成されたディレクトリに移動して依存関係をインストールする
% cd my-app
% npm install
- 開発サーバーを開始します。
npm run dev
ブラウザで http://localhost:5173
を開き、初期のReactアプリが動作していることを確認します。
Reactアプリの修正
以下のコードをsrc/App.jsx
に記述し、 Lambdaとの連携機能を追加します。
これにより、S3でホストしたアプリから、バックエンドのAWS Lambdaに処理を引き渡します。https://<API_GATEWAY_URL>
は後述するLambda関数のデプロイ後に作成されるAPI GatewayのエンドポイントURLを記載します。
import React, { useState } from 'react';
import './App.css';
function App() {
const [message, setMessage] = useState('Click the button to fetch data.');
const fetchData = async () => {
setMessage('Fetching data...');
try {
const response = await fetch('https://<API_GATEWAY_URL>');
const data = await response.json();
setMessage(`Response: ${data.message}`);
} catch (error) {
setMessage('Error fetching data.');
console.error(error);
}
};
return (
<div className="App">
<header className="App-header">
<h1>Vite + React + Lambda Example</h1>
<button onClick={fetchData}>Fetch Data</button>
<p>{message}</p>
</header>
</div>
);
}
export default App;
以下のスタイルを src/App.css
に記述して、画面の見た目を整えます。
.App {
text-align: center;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
button {
padding: 10px 20px;
font-size: 16px;
margin-top: 20px;
cursor: pointer;
background-color: #61dafb;
border: none;
border-radius: 5px;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #21a1f1;
}
p {
margin-top: 20px;
font-size: 18px;
}
修正後の画面は以下のようになっています。
次に、ReactアプリをS3でホストできる静的ファイルに変換します。
% npm run build
これにより、dist/
ディレクトリが作成されます。この中に公開用のHTML、CSS、JavaScriptファイルが含まれています。
これでReactのサンプルアプリができたね!
うん、次はS3にデプロイだね!
S3バケットの作成&設定
S3バケットの作成
AWSマネジメントコンソールにログインし、S3のサービスを選択します。
S3バケットを作成します。
- バケットの設定:
- バケット名: 一意の名前を設定(例:
my-app-s3-lambda-hosting
)。 - リージョン: 希望するリージョンを選択。
- 「パブリックアクセスをブロック」: チェックを外す(後で公開設定を変更)。
- 他の設定はデフォルトでOK。
- バケット名: 一意の名前を設定(例:
- バケットを作成をクリック。
ReactアプリをS3にアップロード
- ビルドしたファイルをアップロード
- AWSコンソールで作成したバケットを選択。
- 「アップロード」ボタンをクリックし、
dist/
フォルダ内のすべてのファイルを選択してアップロード。
S3バケットの設定
アプリをホストするために、作成したバケットのプロパティを選択し、「静的ウェブサイトホスティング」の編集ボタンを押下します。
「静的ウェブサイトホスティング」を有効にします。
インデックスドキュメントには「index.html」を指定します。
また、バケットポリシーも以下の形式で設定してください。your-backet-name
には、自身で作成したS3バケット名を入力します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-backet-name/*"
}
]
}
このバケットポリシーは、作成したバケット内のすべてのオブジェクトを、誰でも読み取れる(公開アクセス可能)ように設定しています。
この設定がないと、アプリが外部から見えないんだよね?
その通り!セキュリティとアクセス許可は非常に大事だよ!
S3でホストしたWebアプリへのアクセス
これでS3バケットを使った静的ウェブサイトのホスティングが完了したよ。
実際にURLにアクセスして動作を確認してみよう!
S3バケットのプロパティの「静的ウェブサイトホスティング」に記載されている「バケットウェブサイトエンドポイント」のURLにアクセスします。
Webアプリにアクセスできれば成功です。
Lambda関数へのデプロイ
バックエンドの処理をLambda関数にデプロイします。
デプロイには、Serverless Frameworkを用います。Serverless Frameworkは、開発者がAWS Lambdaや他のサーバーレスアーキテクチャを迅速かつ容易に構築・デプロイするための強力なツールです。
インストール手順および基本的な使い方については、以下の記事に記載しているので、必要に応じてご参照ください。
Lambda関数の作成
以下のコマンドでlambda関数用のディレクトリと空ファイルを作成します。
% mkdir lambda
% cd lambda
% touch lambda_function.py
% touch serverless.yaml
lambda_function.pyを以下の内容で更新します。
import json
def lambda_handler(event, context):
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json'
},
'body': json.dumps({'message': 'Hello from Lambda!'})
}
Serverless Frameworkでは、serverless.yamlでデプロイするLambda関数の設定を記載します。今回の検証では、以下のように記載します。your-organization
は、自身のServerless Frameworkの組織名を入力します。your-s3-endpoint-url
は、自身のS3バケットのエンドポイントURLを入力します。
org: your-organization
app: my-app-s3-lambda-hosting
service: my-app-s3-lambda-hosting
provider:
name: aws
runtime: python3.12
region: ap-northeast-1
httpApi:
cors:
allowedOrigins:
- your-s3-endpoint-url
allowedMethods:
- GET
allowedHeaders:
- Content-Type
- Authorization
- x-requested-with
- origin
- accept
environment:
PYTHONPATH: "/var/task/src:/opt/python"
functions:
lambda_api:
handler: lambda_function.lambda_handler
timeout: 30
events:
- httpApi:
path: /lambda
method: get
Lambdaに対してデプロイ
以下のコマンドでLambdaに対してデプロイします。
% serverless deploy
デプロイが成功すると、以下のようにLambdaコンソール画面から関数が作成(更新)されていることを確認できます。
API GatewayのCORSの設定
ReactアプリからAPIを呼び出せるようにするため、API GatewayでCORS設定を有効化します。
これにより、異なるオリジン間のリクエストが許可され、Lambda関数を安全に呼び出すことができます。 (今回の場合は、S3バケットから、Lambdaに対するリクエスト許可)
ちなみにCORS設定が正常に行えていない場合は、以下のようなエラーが出ます。
CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource
以下は、手動でAPI GatewayのCORS設定を行う手順です。
- LambdaにGETリクエストを送るためのAPI Gatewayを作成します。
- 作成したAPI GatewayでCORS設定を開きます。
- 許可するオリジン、ヘッダー、メソッドを追加します。
(Access-Control-Allow-OriginにはS3バケットのエンドポイントURLを記載します。)
なお、serverless.yamlでデプロイした場合は、自動でAPI Gatewayが作成されています。念のため、API Gatewayの作成およびCORSが完了していることを確認しましょう。
S3とLambdaによるReactアプリの動作確認
S3とLambdaによるReactアプリの動作を確認します。
構成図は以下の通りです。
API GatewayのエンドポイントURLを確認し、フロントエンドのApp.jsx
に反映します。
- Serverless Frameworkでデプロイを実行すると、デプロイ完了後のログにエンドポイントURLが表示されます。
% serverless deploy
#出力例
Service Information
service: post-pilot-s3-hosting
stage: dev
region: ap-northeast-1
stack: post-pilot-s3-hosting-dev
resources: 16
api endpoint: https://<API-ID>.execute-api.ap-northeast-1.amazonaws.com/lambda
- AWS Management Console で確認する場合、
- 該当のAPIを選択:
- デプロイしたAPIの名前(例:
dev-my-app-s3-lambda-hosting
)をクリックします。 - ステージを確認:
- 左側のメニューから
Stages
を選択し、該当のステージ(例:dev
)をクリックします。 - エンドポイントURLを確認:
- ステージ設定画面でエンドポイントURLが表示されます。
App.jsx
に、API GatewayのエンドポイントURLを記載します。
const response = await fetch('https://cz6tlba49h.execute-api.ap-northeast-1.amazonaws.com/lambda');
再度、以下のコマンドでフロントエンドのリソースをビルドし、S3バケットにアップロードします。
nom run build
S3バケットのエンドポイントURLにアクセスします。
Webアプリの「Fetch Data」ボタンを押下します。
「Response: Hello fron Lambda!」と出力されれば、Lambdaと連携成功です。
これでS3とLambdaを使ったフロントエンドとバックエンドの連携が完了したね!
次は独自ドメインにも挑戦してみよう!
独自ドメインの設定
さて、成功したReactアプリをS3でホストできたところで、次は独自ドメインを取得して、アプリケーションを一層魅力的にしましょう!
ここでは、AWSのRoute 53を使ってドメインを設定する方法を見ていきます。
Route 53でドメイン取得
- AWSマネジメントコンソールに戻り、Route 53を開きます。
- 左側のメニューから「ドメインを登録」を選択。
- 好きなドメイン名を入力して、利用可能か確認します。
- 利用可能な場合は、ドメインを選択して必要な情報を入力し、購入します。
購入から数分後にドメイン登録完了メールが送られてきます。
この手順でドメインが手に入るんだ!簡単だね!
それじゃあ、次はドメインをS3バケットに接続しよう!
S3バケットにドメインを接続
取得したドメインをS3バケットに接続するためには、バケット名をドメイン名と一致させる必要があります。
以下の手順で設定を進めます。
- 取得したドメイン名と同じ名前のS3バケットを作成します(※)。
- Route 53に戻り、登録したドメインの「ホストゾーン」を選択します。
- 「タイプA」レコードを作成し、S3バケットのエンドポイントを指定します。レコードの詳細を以下のように設定します。
- レコードタイプ: A – IPv4 アドレス。
- エイリアス: 有効にする。
- エイリアスターゲット:対応する S3 バケットの静的ホスティングエンドポイントを選択します。
(※)既存のS3バケットをコピーしたい場合は、以下のAWS CLIコマンドで実行できます。
% aws s3 mb s3://新規S3のバケット名
% aws s3 sync s3://既存S3のバケット名 s3://新規S3のバケット名
最後に本当にS3を作成できたか確認
% aws s3 ls
S3バケットを新規作成した場合、「パブリックアクセスをオフの無効化」、「バケットポリシーによる外部アクセスの許可」、「静的ウェブホスティングの有効化」も忘れずに行います。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-backet-policy/*"
}
]
}
S3 バケットのエンドポイントは、バケットの「プロパティ」タブにある「静的ウェブサイトホスティング」のセクションで確認できます。
S3バケットのエンドポイントURLでWebサイトが表示されることを確認します。
例:http://<your-bucket-name>.s3-website-<region>.amazonaws.com
自身で設定したドメイン名でWebアプリにアクセスできることを確認します。
S3のエンドポイントURLと同様に、Webアプリが表示されればドメイン接続完了です。
例:http://your-domain.click
これでドメインがアプリにリンクされたんだね!
これで取得したドメイン名でアクセス可能になったよ。
一般的なWebアプリっぽくなってきたね。
さあ、最後のステップだ!
HTTPSの有効化
Certificate Managerを利用してSSL/TLS証明書
安全なウェブサイトにはHTTPSは必須です。
これを実現するために、AWSのCertificate Managerを利用してSSL/TLS証明書を取得しましょう。
- AWSコンソールへのアクセス
- AWS Certificate Manager (ACM) に移動します。
- リージョンの変更
- us-east-1リージョンに変更します。
(後ほどCloudFrontdでHTTPS化をするためには、us-east-1で証明書を発行する必要があるためです。)
- us-east-1リージョンに変更します。
- 「証明書のリクエスト」を選択
- ACM ダッシュボードで「証明書をリクエスト」をクリックします。
- 証明書タイプを選択
- 「パブリック証明書」を選択し、「次へ」をクリックします。
- ドメイン名を入力
- 証明書を適用するドメイン名を正確に入力します。
- 例:
example.com
(ルートドメイン)やwww.example.com
(サブドメイン)。(ワイルドカード証明書を利用する場合、*.example.com
を入力して、すべてのサブドメインをカバーします。)
- 例:
- 証明書を適用するドメイン名を正確に入力します。
- 検証方法とキーアルゴリズムの選択
- 検証方法:「DNS 検証」を選択。
- キーアルゴリズム:「RSA 2048」を選択。
- 設定を確認して送信
- 入力内容を確認し、「リクエスト」をクリック。
- ACMの画面から、該当のドメインの証明書を選択し、ドメイン項目の「Route53でレコードを作成」を押下します。(これにより、対象ドメインのホストゾーンにACMが発行したCNAMEの値でホストゾーンが作成されます。Route53のコンソール画面からも作成は可能ですが、こちらの方が手順が少ないので、おすすめです。)
- ACM に戻る
- DNS レコードを追加したら、ACM の証明書詳細ページで検証が完了するのを待ちます。
- 検証が成功すると、証明書のステータスが「発行済み」に変わります。
(DNS の更新が反映されるまで、数分から数十分かかる場合があります。)
CloudFront を使用した HTTPS 設定手順
- AWS マネジメントコンソールで CloudFront を開く
- AWS マネジメントコンソールから CloudFront にアクセス。
- 「ディストリビューションを作成」をクリック
- 「Web」を選択します(デフォルトで選択されている場合もあります)。
- オリジンを設定
- オリジンドメイン:
- S3 バケットの静的ウェブホスティングエンドポイントを入力。
- 例:
example.com.s3-website-ap-northeast-1.amazonaws.com
- 例:
- S3 バケットの静的ウェブホスティングエンドポイントを入力。
- プロトコルポリシー:
- 「HTTP」を選択。
- オリジンドメイン:
- キャッシュ設定
- キャッシュポリシー:
- デフォルトで問題ない場合が多いですが、カスタムキャッシュを設定する場合は「キャッシュポリシーの作成」から設定を追加。
- キャッシュポリシー:
- ビューアプロトコルポリシー
- 「リダイレクト HTTP → HTTPS」 を選択。
- これにより、ユーザーが HTTP を使用してアクセスした場合に自動で HTTPS にリダイレクトされます。
- 「リダイレクト HTTP → HTTPS」 を選択。
- 証明書の選択
- ACM 証明書を使用:
- 「カスタム SSL 証明書を選択」をクリック。
- 先ほど ACM で発行された証明書を選択します。
- 代替ドメイン名 (CNAME)
- CloudFront で使用するドメイン名を指定します(例:
example.com
やwww.example.com
)。
- CloudFront で使用するドメイン名を指定します(例:
- ACM 証明書を使用:
- デフォルトルートオブジェクト
- index.htmlを指定します。
- 他の設定を確認
- 他の設定はデフォルトで問題ない場合が多いですが、必要に応じてログ記録やアクセス制限を設定できます。
- ディストリビューションを作成
- 「作成」をクリックして、CloudFront ディストリビューションを作成します。
- Route 53 のホストゾーンを開く
- AWS マネジメントコンソールで Route 53 に移動します。
- 対象ドメインのホストゾーンを選択。
- 新しい A レコードを作成
- レコード名: 空欄(ルートドメインの場合)。
- レコードタイプ:
A - IPv4 アドレス
を選択。
(既にAレコードを作成済みの場合は、既存のAレコードのエイリアスをCloudFrontに変更し、保存します。) - エイリアスを有効にする: チェックを入れます。
- エイリアスターゲット:
- CloudFront のディストリビューションを選択します
(例:example.cloudfront.net
)。
- CloudFront のディストリビューションを選択します
- 保存
- 設定を保存します。
ドメインが変更になってことに伴い、API GatewayのCORSの設定も忘れずに行う必要があります。
CloudFrontを使えば、応答速度もアップするんだ!
これで、世界中のユーザーにも安全かつ快適にWebアプリを提供できるってことだね!
まとめ
これで、AWS の複数のサービスを連携させ、React アプリケーションをホストするプロセスを完成させることができました。S3、Lambda、Route 53、CloudFront、そして ACM を組み合わせることで、高性能でセキュアなウェブアプリケーションが構築できました。
以下は、本記事の内容を振り返りつつ、各ステップの意義と利点を整理したまとめです。
S3 は、静的ウェブサイトをホストするのに最適なストレージサービスです。React アプリケーションのビルド済みファイル(HTML、CSS、JavaScript)を S3 にアップロードし、そこからエンドユーザーに配信します。
- 利点:
- 高い可用性と耐久性を誇るストレージ。
- AWS が提供するスケーラブルなインフラストラクチャ。
- シンプルなアップロード手順で静的コンテンツをホスト可能。
Lambda を利用することで、バックエンドの API を簡単に構築できます。サーバーレスアーキテクチャにより、サーバー管理の負担を軽減しつつ、必要な時だけリソースをスケールします。
- 利点:
- スケーラブルなサーバーレス環境。
- イベント駆動型で高パフォーマンスな API を実現。
- 使用した分だけ課金されるコスト効率の良さ。
- 工夫点:
- API Gateway と組み合わせて REST API を構築。
Route 53 は、AWS が提供する高可用性の DNS サービスであり、独自ドメインの管理や HTTPS 証明書の設定に役立ちます。
- 利点:
- AWS 内の他のサービス(CloudFront、S3 など)との統合が容易。
- ドメイン管理と DNS 設定の一元化。
- 高速な名前解決。
- 工夫点:
- エイリアスレコードを利用して CloudFront に直接マッピング。
- DNS レコード設定で CNAME を利用して HTTPS 証明書の所有権を検証。
CloudFront は、ウェブアプリケーションをエンドユーザーに高速かつセキュアに配信するための AWS のコンテンツ配信ネットワーク (CDN) です。ACM を利用して HTTPS を有効化し、セキュリティを強化します。
- 利点:
- グローバルに分散したエッジロケーションで高速配信。
- HTTPS によるセキュアな接続を簡単に設定。
- 工夫点:
- ビューアプロトコルポリシーで HTTP リクエストを HTTPS にリダイレクト。
このように、AWS の強力なサービス群を活用することで、安全で高速、かつコスト効率の高い React アプリケーションのホスティングが実現しました。AWS の柔軟性と拡張性を生かして、さらにスケーラブルなウェブアプリケーションを構築していきましょう!
ねえ、チーズくん、AWSを使ってReactアプリを簡単にホストする方法知ってる?