AWS WebAP + RDS 2層アーキテクチャ ハンズオン手順書

v4.2 / 作成日: 2026-06-07 / ALB + WebAPサーバ冗長化(プライベートサブネット)+ RDS PostgreSQL Multi-AZ / AWSマネジメントコンソール操作

目次

  1. アーキテクチャ概要
  2. 前提条件・事前準備
  3. IAMロールの作成
  4. VPC・ネットワーク構築
    1. VPCの作成
    2. サブネットの作成(6つ)
    3. Internet Gatewayの作成・アタッチ
    4. NAT Gatewayの作成
    5. ルートテーブルの設定
  5. セキュリティグループの作成(3つ)
  6. RDS サブネットグループの作成
  7. RDS MySQL の作成
  8. ターゲットグループの作成
  9. ALBの作成
  10. EC2インスタンス起動:WebAPサーバ(2台)
  11. WebAPサーバセットアップ(Nginx + Node.js)
  12. RDSのデータ初期化
  13. 動作確認・冗長性テスト
  14. リソース削除(クリーンアップ)
  15. 完了チェックリスト

1. アーキテクチャ概要

🌐 インターネット(エンドユーザー)
↕ HTTP 80
VPC: handson-vpc (10.0.0.0/16) / リージョン: ap-northeast-1(東京)
⚖️
ALB(handson-alb)― インターネット向け
パブリックサブネット 1a + 1c に配置 / HTTP:80 / WebAPサーバ2台に振り分け
↕ HTTP 80
🖥️
WebAPサーバ EC2 ×2 — プライベートサブネット(1a・1c)
handson-webap-1a (10.0.3.0/24) / handson-webap-1c (10.0.4.0/24) / インターネット非公開
🌐 Nginx(:80) → localhost → ⚙️ Node.js(:8080) 同一サーバ内で処理
↕ PostgreSQL 5432
🗄️
RDS PostgreSQL 16(Multi-AZ)― プライベートサブネット(DB)
Primary: 10.0.5.0/24 (1a) / Standby: 10.0.6.0/24 (1c) / 自動フェイルオーバー / PostgreSQL 16
v4.2の変更点WebAPサーバを プライベートサブネットに移動 しました。ALBのみパブリックサブネットに配置し、EC2はインターネットに直接公開しない安全な構成です。WebAP EC2のSSM接続・パッケージ取得のためNAT Gatewayを配置しています。

構成リソース一覧

リソース名前設定値
VPChandson-vpc10.0.0.0/16
パブリックサブネット(ALB-1a)handson-subnet-public-1a10.0.1.0/24 / ap-northeast-1a / ALBのみ配置
パブリックサブネット(ALB-1c)handson-subnet-public-1c10.0.2.0/24 / ap-northeast-1c / ALBのみ配置
プライベートサブネット(WebAP-1a)handson-subnet-private-webap-1a10.0.3.0/24 / ap-northeast-1a
プライベートサブネット(WebAP-1c)handson-subnet-private-webap-1c10.0.4.0/24 / ap-northeast-1c
プライベートサブネット(DB-1a)handson-subnet-private-db-1a10.0.5.0/24 / ap-northeast-1a
プライベートサブネット(DB-1c)handson-subnet-private-db-1c10.0.6.0/24 / ap-northeast-1c
Internet Gatewayhandson-igwVPCにアタッチ
NAT Gatewayhandson-natgwpublic-1a に配置 / WebAP EC2のアウトバウンド通信用
ALBhandson-albインターネット向け / HTTP:80
ターゲットグループhandson-tg-webapHTTP:80 / WebAP EC2 2台
EC2(WebAP-1a)handson-webap-1at2.micro / Nginx + Node.js
EC2(WebAP-1c)handson-webap-1ct2.micro / Nginx + Node.js
RDShandson-rdsPostgreSQL 16 / db.t3.micro / Multi-AZ
セキュリティグループsg-alb / sg-webap / sg-rds3つ

コスト目安(数時間で削除した場合)

リソース概算料金備考
EC2 t2.micro × 2台無料枠内新規アカウント12ヶ月以内
ALB × 1台約$0.028/時間ハンズオン後すぐ削除
RDS PostgreSQL db.t3.micro Multi-AZ約$0.052/時間必ず削除すること
NAT Gateway × 1台約$0.062/時間WebAP EC2のSSM接続・パッケージ取得に必要。必ず削除すること。
重要ALB・RDSは時間課金です。ハンズオン終了後は必ず全リソースを削除してください。

2. 前提条件・事前準備

項目内容
AWSアカウントAdministratorAccess権限を持つIAMユーザー
リージョン東京(ap-northeast-1)― コンソール右上で必ず確認
ブラウザChrome / Edge / Firefox(最新版)
接続方式EC2へのアクセスはすべて Session Manager(SSH鍵不要・コンソールのブラウザから接続)を使用します。

3. IAMロールの作成(SSM接続用)

IAM

EC2インスタンスへのSession Manager接続に必要なIAMロールを作成します。

1
信頼されたエンティティの選択
項目
エンティティタイプAWSのサービス
ユースケースEC2(「EC2」で検索して選択)
次へ
2
許可ポリシーの追加

検索欄に AmazonSSMManagedInstanceCore と入力 → チェックを入れる

次へ
3
ロール名を入力して作成
項目
ロール名handson-ec2-ssm-role
ロールを作成

4. VPC・ネットワーク構築

4-1. VPCの作成

1
VPC設定を入力
項目
作成するリソースVPCのみ
名前タグhandson-vpc
IPv4 CIDR10.0.0.0/16
テナンシーデフォルト
VPCを作成
2
DNS ホスト名を有効化

handson-vpc を選択 → アクション → 「VPCの設定を編集」

項目
DNS ホスト名を有効化チェックを入れる(有効化)
保存

4-2. サブネットの作成(6つ)

1
VPCに handson-vpc を選択し、6つのサブネットを追加
サブネット名AZCIDR用途
handson-subnet-public-1aap-northeast-1a10.0.1.0/24ALB-1a
handson-subnet-public-1cap-northeast-1c10.0.2.0/24ALB-1c
handson-subnet-private-webap-1aap-northeast-1a10.0.3.0/24WebAP-1a
handson-subnet-private-webap-1cap-northeast-1c10.0.4.0/24WebAP-1c
handson-subnet-private-db-1aap-northeast-1a10.0.5.0/24DB-1a
handson-subnet-private-db-1cap-northeast-1c10.0.6.0/24DB-1c

「新しいサブネットを追加」ボタンで6つをまとめて作成し、サブネットを作成

設計ポイントALBはパブリックサブネット、WebAP EC2はプライベートサブネットに分離することで、EC2がインターネットに直接公開されない安全な構成になります。
2
パブリックサブネット 2つのパブリックIP自動割り当てを有効化(ALB用)

handson-subnet-public-1a を選択 → アクション → 「サブネットの設定を編集」

項目
パブリック IPv4 アドレスの自動割り当てを有効化チェックを入れる
保存

handson-subnet-public-1c についても同様に設定します。

4-3. Internet Gatewayの作成・アタッチ

1
作成してVPCにアタッチ
項目
名前タグhandson-igw
インターネットゲートウェイを作成

作成後、画面上部のバナーの「VPCにアタッチ」をクリック(または アクション → 「VPCにアタッチ」)

項目
使用可能な VPChandson-vpc(プルダウンから選択)
インターネットゲートウェイのアタッチ

状態が 「Attached」 になっていることを確認します。

4-4. NAT Gatewayの作成

1
NAT Gatewayを作成
項目
名前handson-natgw
サブネットhandson-subnet-public-1a(パブリックサブネットに配置)
接続タイプパブリック
Elastic IP 割り当て IDElastic IP を割り当て をクリックして新規EIPを取得
NAT ゲートウェイを作成
注意NAT Gatewayのステータスが 「Available」 になるまで約1〜3分かかります。次の手順(ルートテーブル設定)を進める前に「Available」を確認してください。
課金注意NAT Gatewayは約$0.062/時間かかります。ハンズオン終了後は必ず削除してください。

4-5. ルートテーブルの設定

1
パブリック用ルートテーブルを作成
項目
名前handson-rt-public
VPChandson-vpc
ルートテーブルを作成
2
インターネットへのルートを追加

handson-rt-public を選択 → 「ルート」タブ → ルートを編集ルートを追加

送信先ターゲット
0.0.0.0/0Internet Gateway → handson-igw
変更を保存
3
パブリックサブネット 2つを関連付け

「サブネットの関連付け」タブ → サブネットの関連付けを編集

以下 2つにチェック → 関連付けを保存

  • handson-subnet-public-1a
  • handson-subnet-public-1c
NoteプライベートDBサブネットはデフォルトのメインルートテーブル(ローカル通信のみ)を使用するため、追加のルートテーブル設定は不要です。RDSはインターネットに接続しません。
4
WebAP用プライベートルートテーブルを作成

新しいルートテーブルを作成します:

項目
名前handson-rt-private-webap
VPChandson-vpc
ルートテーブルを作成
5
NAT GatewayへのルートをWebAP用ルートテーブルに追加

handson-rt-private-webap を選択 → 「ルート」タブ → ルートを編集ルートを追加

送信先ターゲット
0.0.0.0/0NAT Gateway → handson-natgw
変更を保存
役割このルートにより、プライベートサブネットのWebAP EC2からのアウトバウンド通信(SSM接続・パッケージ取得など)がNAT GW経由でインターネットに出られるようになります。
6
WebAPプライベートサブネット 2つを関連付け

「サブネットの関連付け」タブ → サブネットの関連付けを編集

以下 2つにチェック → 関連付けを保存

  • handson-subnet-private-webap-1a
  • handson-subnet-private-webap-1c

5. セキュリティグループの作成(3つ)

作成順序依存関係があるため、必ず ① → ② → ③ の順に作成してください。
1
① sg-alb(ALB用)ALB
項目
セキュリティグループ名sg-alb
説明ALB security group
VPChandson-vpc

インバウンドルール:

タイププロトコルポートソース説明
HTTPTCP800.0.0.0/0インターネットからのHTTP
HTTPSTCP4430.0.0.0/0インターネットからのHTTPS

アウトバウンドルール:デフォルト(すべてのトラフィックを許可)のまま

セキュリティグループを作成
2
② sg-webap(WebAPサーバ用)WebAP
項目
セキュリティグループ名sg-webap
説明WebAP server security group
VPChandson-vpc

インバウンドルール:

タイププロトコルポートソース説明
HTTPTCP80sg-alb のSG IDALBからのみ許可(直接アクセス不可)
Tipソースに sg-alb のIDを指定することで、ALBを経由したトラフィックのみを受け付けます。インターネットから直接 EC2 へのアクセスを遮断できます。
セキュリティグループを作成
3
③ sg-rds(RDS用)DB層
項目
セキュリティグループ名sg-rds
説明RDS PostgreSQL security group
VPChandson-vpc

インバウンドルール:

タイププロトコルポートソース説明
PostgreSQLTCP5432sg-webap のSG IDWebAPサーバからのみ許可
セキュリティグループを作成

6. RDS サブネットグループの作成

DB層

RDS Multi-AZ配置に必要な、2AZにまたがるサブネットグループを作成します。

1
サブネットグループの設定
項目
名前handson-db-subnet-group
説明DB subnet group for Multi-AZ RDS
VPChandson-vpc
アベイラビリティーゾーンap-northeast-1a と ap-northeast-1c の両方にチェック
サブネットhandson-subnet-private-db-1ahandson-subnet-private-db-1c を選択
作成

7. RDS PostgreSQL の作成

DB層
重要RDSの作成には約10〜15分かかります。すべての設定を確認してから「作成」をクリックしてください。
1
データベース作成方法・エンジンの選択
項目
データベース作成方法標準作成
エンジンタイプPostgreSQL
エンジンバージョンPostgreSQL 16.x(リストの最新版)
2
テンプレートと可用性の設定
項目
テンプレート開発/テスト
デプロイオプションマルチ AZ DB インスタンス
冗長化のため必ず選択。プライマリ(1a)障害時にスタンバイ(1c)へ自動フェイルオーバーします。
Multi-AZ の仕組みプライマリDB(1a)とスタンバイDB(1c)を自動同期します。プライマリに障害が発生すると通常1〜2分でスタンバイへ切り替わります。アプリはエンドポイント(DNS名)を変えるだけで自動的に切り替え後のDBに接続できます。
3
設定(DBインスタンス名・認証情報)
項目
DB インスタンス識別子handson-rds
マスターユーザー名admin
認証情報の管理セルフマネージド
マスターパスワードAdminPass123!
パスワードの確認AdminPass123!
4
インスタンスの設定
項目
DB インスタンスクラスバースト可能クラス(t クラスを含む)db.t3.micro
5
ストレージ
項目
ストレージタイプ汎用 SSD (gp2)
割り当てられたストレージ20 GiB
ストレージの自動スケーリング無効(チェックを外す)(ハンズオン用)
6
接続設定
項目
コンピューティングリソースEC2 コンピューティングリソースに接続しない
VPChandson-vpc
DB サブネットグループhandson-db-subnet-group
パブリックアクセスなし(インターネットから直接アクセス不可)
VPC セキュリティグループ既存の選択sg-rds
デフォルトのセキュリティグループは削除して sg-rds のみを選択
アベイラビリティーゾーンap-northeast-1a(プライマリ)
7
追加設定

「追加設定」セクションをクリックして展開します。

項目
最初のデータベース名handson_db
ここを空のままにするとデータベースが作成されません。必ず入力してください。
自動バックアップを有効化チェックを外す(ハンズオン用)
削除保護の有効化チェックを外す(削除しやすくするため)
データベースの作成
注意ステータスが 「利用可能」 になるまで10〜15分かかります。次の手順(ターゲットグループ・ALB・EC2の作成)を進めながら待ちます。
RDS作成完了後、「エンドポイント」をメモしてください。
例: handson-rds.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com(ポート: 5432

8. ターゲットグループの作成

ALB
1
WebAPサーバ用ターゲットグループを作成
項目
ターゲットタイプインスタンス
ターゲットグループ名handson-tg-webap
プロトコルHTTP
ポート80
VPChandson-vpc
プロトコルバージョンHTTP1

ヘルスチェック設定:

項目
ヘルスチェックプロトコルHTTP
ヘルスチェックパス/health
正常のしきい値2
非正常のしきい値3
間隔30 秒
次へ → ターゲットの登録は後の手順で行うため ターゲットグループの作成

9. ALBの作成

ALB
1
基本設定
項目
ロードバランサー名handson-alb
スキームインターネット向け
IP アドレスタイプIPv4
2
ネットワークマッピング(2AZを選択)
項目
VPChandson-vpc
マッピング(AZ 1)ap-northeast-1a → handson-subnet-public-1a
マッピング(AZ 2)ap-northeast-1c → handson-subnet-public-1c
NoteALBは必ず2つ以上のAZを選択する必要があります。
3
セキュリティグループ
項目
セキュリティグループsg-alb(デフォルトのSGは削除して sg-alb のみ選択)
4
リスナーとルーティング
項目
プロトコルHTTP
ポート80
デフォルトアクションhandson-tg-webap に転送
ロードバランサーの作成
確認作成後、ALBの「DNS 名」をメモしてください。これがアクセスURLになります。
例: handson-alb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com

10. EC2インスタンス起動:WebAPサーバ(2台)

WebAP
1
1台目:handson-webap-1a(ap-northeast-1a)
項目
名前handson-webap-1a
AMIAmazon Linux 2023 AMI(64ビット x86)
インスタンスタイプt2.micro
キーペアキーペアなしで続行(Session Manager使用)
VPChandson-vpc
サブネットhandson-subnet-private-webap-1a
パブリック IP の自動割り当て無効(デフォルト)
セキュリティグループsg-webap(既存のSGを選択)
ストレージ8 GiB / gp3
IAM インスタンスプロフィールhandson-ec2-ssm-role(「高度な詳細」を展開して設定)
インスタンスを起動
2
2台目:handson-webap-1c(ap-northeast-1c)

「インスタンスを起動」から以下の項目だけ変更して同じ設定で起動します:

項目
名前handson-webap-1c
サブネットhandson-subnet-private-webap-1c
インスタンスを起動
確認2台ともステータスが「実行中」になるまで待ちます(約1〜2分)。
3
ターゲットグループへのインスタンス登録

インスタンス一覧から handson-webap-1ahandson-webap-1c にチェック

項目
ポート80
保留中として以下を含めるターゲットの登録
注意この時点でNginx未インストールのためヘルスチェックは「unhealthy」になります。手順11完了後に「healthy」になります。

11. WebAPサーバセットアップ(Nginx + Node.js)

WebAP

handson-webap-1a と handson-webap-1c の両方で、同じ手順を実行します。

Session Managerで接続

接続できない場合インスタンス起動直後はSSMエージェントの初期化に2〜3分かかります。しばらく待ってから再試行してください。
1
ec2-userに切り替え
sudo -i -u ec2-user
cd ~
2
Nginxのインストールと起動
sudo dnf update -y
sudo dnf install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
sudo systemctl status nginx

Active: active (running) と表示されれば起動成功です。

3
Node.jsのインストール
sudo dnf install -y nodejs npm
node -v
npm -v

バージョン番号が表示されれば成功です。

4
Node.jsアプリケーションの作成

【RDSエンドポイント】 を手順7でメモしたRDSエンドポイントに置き換えて実行します:

mkdir ~/app && cd ~/app
npm init -y
npm install express pg
cat > ~/app/app.js <<'EOF'
const express = require('express');
const { Pool } = require('pg');
const os      = require('os');
const app     = express();

const pool = new Pool({
  host:     '【RDSエンドポイント】',
  port:     5432,
  user:     'admin',
  password: 'AdminPass123!',
  database: 'handson_db',
  ssl:      { rejectUnauthorized: false },
  max:      10
});

app.get('/health', (req, res) => {
  res.json({ status: 'ok', server: os.hostname() });
});

app.get('/', (req, res) => {
  res.json({
    message: 'WebAP server is running!',
    server:  os.hostname(),
    tier:    'webap'
  });
});

app.get('/users', async (req, res) => {
  try {
    const result = await pool.query('SELECT * FROM users ORDER BY id');
    res.json({ count: result.rowCount, users: result.rows, server: os.hostname() });
  } catch (err) {
    res.status(500).json({ error: err.message, server: os.hostname() });
  }
});

app.listen(8080, '127.0.0.1', () => {
  console.log('Node.js app listening on localhost:8080');
});
EOF
NoteNode.jsは 127.0.0.1(ローカルループバック)のみでリッスンしています。外部から直接8080へのアクセスはできず、Nginx経由のみアクセス可能です。RDSへの接続はSSL(ssl: { rejectUnauthorized: false })を使用しています。
5
pm2でNode.jsを常駐起動
sudo npm install -g pm2
cd ~/app && pm2 start app.js --name webap-app
pm2 save
pm2 startup

pm2 startup が出力するコマンド(sudo env PATH=... で始まる行)をコピーして実行します。

pm2 status

status: online と表示されれば起動成功です。

6
NginxをNode.jsへのリバースプロキシとして設定
sudo tee /etc/nginx/conf.d/webap.conf <<'EOF'
server {
    listen 80;
    server_name _;

    location /health {
        proxy_pass         http://127.0.0.1:8080/health;
        proxy_set_header   Host $host;
        access_log         off;
    }

    location / {
        proxy_pass         http://127.0.0.1:8080;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_connect_timeout 10s;
        proxy_read_timeout    60s;
    }
}
EOF

sudo nginx -t

syntax is ok と表示されたら:

sudo systemctl reload nginx
構成まとめインターネット → ALB(:80) → Nginx(:80) → localhost:8080 → Node.js → RDS PostgreSQL(5432)

⬛ handson-webap-1c でも手順1〜6を同様に実行します。

12. RDSのデータ初期化

DB層

WebAPサーバのどちらか1台(handson-webap-1a)のSession Managerから実行します。

1
PostgreSQLクライアントのインストール
sudo dnf install -y postgresql16
NoteRDSのPostgreSQLバージョンに合ったクライアントを使用します。バージョンが異なる場合は postgresql15 など適宜変更してください。
2
RDSへ接続
psql -h 【RDSエンドポイント】 -U admin -d handson_db

パスワードを求められたら AdminPass123! を入力してEnter(入力文字は画面に表示されません)。

handson_db=> プロンプトが表示されれば接続成功です。

接続できない場合環境変数でパスワードを渡すと対話入力を省略できます:
PGPASSWORD='AdminPass123!' psql -h 【RDSエンドポイント】 -U admin -d handson_db
3
テーブルとサンプルデータの作成
-- テーブル作成
CREATE TABLE users (
  id         SERIAL PRIMARY KEY,
  name       VARCHAR(100) NOT NULL,
  email      VARCHAR(200) NOT NULL UNIQUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- サンプルデータ挿入
INSERT INTO users (name, email) VALUES
  ('田中 太郎', 'taro@example.com'),
  ('鈴木 花子', 'hanako@example.com'),
  ('佐藤 一郎', 'ichiro@example.com');

-- 確認
SELECT * FROM users;

-- 切断
\q

3件のレコードが表示されれば成功です。

MySQLとの主な違いAUTO_INCREMENTSERIAL(PostgreSQL)、ENGINE=InnoDB は不要、終了コマンドは EXIT; の代わりに \q を使用します。

13. 動作確認・冗長性テスト

13-1. ターゲットグループのヘルスチェック確認

1
両インスタンスが「healthy」になっていることを確認

handson-webap-1ahandson-webap-1c「healthy」 になっていることを確認します。

unhealthy の場合NginxとNode.jsの両方が起動しているか確認します。pm2 status でNode.jsの状態、sudo systemctl status nginx でNginxの状態を確認してください。

13-2. ブラウザからのエンドツーエンド確認

1
ALBのDNS名でアクセス

手順9でメモした ALBのDNS名をブラウザのアドレスバーに入力してアクセスします:

URL期待するレスポンス
http://【ALBのDNS名】/{"message":"WebAP server is running!","server":"..."}
http://【ALBのDNS名】/health{"status":"ok","server":"..."}
http://【ALBのDNS名】/usersRDSのusersテーブルデータ(3件)
成功!データが表示されればインターネット → ALB → WebAPサーバ(Nginx+Node.js) → RDS PostgreSQL の動作が確認できました。

13-3. 冗長性(ロードバランシング)の確認

1
serverフィールドでどちらのサーバが応答しているか確認

ブラウザで /health/users に複数回アクセスすると、レスポンスの "server" フィールドが handson-webap-1ahandson-webap-1c で切り替わることを確認します。

Noteブラウザはセッションキープを行うため、シークレットモードや curl を使うと切り替わりがわかりやすくなります。
2
フェイルオーバーテスト(オプション)

EC2コンソールで handson-webap-1a を「停止」すると、ALBが自動的に handson-webap-1c のみにルーティングします。

ブラウザからのアクセスがエラーなく継続できることを確認します。

確認後は handson-webap-1a を「開始」して元の状態に戻してください。

14. リソース削除(クリーンアップ)

重要ALB・RDSは時間課金です。ハンズオン終了後は以下の順番で必ず削除してください。
1
EC2インスタンス 2台を終了
2
ALB を削除
3
ターゲットグループを削除
4
RDS を削除

「最終スナップショットを作成しますか?」→ いいえ を選択
確認テキスト(delete me)を入力して 削除

注意RDS削除には数分かかります。ステータスが「削除中」になっていれば次へ進めます。
5
RDS サブネットグループを削除
6
NAT Gateway を削除

確認テキストを入力して 削除

注意NAT Gatewayの削除には数分かかります。ステータスが「削除済み」になるまで待ってからElastic IPを解放してください。
7
Elastic IP を解放
NoteNAT Gatewayが完全に削除された後でないとEIPを解放できません。
8
Internet Gateway をデタッチ・削除

デタッチ完了後 → 再度 アクション → 「インターネットゲートウェイを削除」

9
セキュリティグループ 3つを削除

sg-rds → sg-webap → sg-alb の順に削除します(依存関係があるため逆順)。

10
サブネット・ルートテーブル・VPC を削除

サブネット 6つ → ルートテーブル(handson-rt-private-webap → handson-rt-public)→ VPC(handson-vpc)の順に削除します。

11
IAMロールを削除

15. 完了チェックリスト

ネットワーク

セキュリティ・IAM

RDS・ALB

EC2・アプリケーション

動作確認

クリーンアップ