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

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

目次

  1. アーキテクチャ概要
  2. 前提条件・事前準備
  3. IAMロールの作成(ECSタスク実行ロール)
  4. VPC・ネットワーク構築
    1. VPCの作成
    2. サブネットの作成(6つ)
    3. Internet Gatewayの作成・アタッチ
    4. NAT Gatewayの作成
    5. ルートテーブルの設定
  5. セキュリティグループの作成(3つ)
  6. ECRリポジトリの作成
  7. Dockerイメージの作成・プッシュ(CloudShell)
  8. RDS PostgreSQL の作成
  9. RDS サブネットグループの作成
  10. ECSクラスターの作成
  11. ECSタスク定義の作成
  12. ターゲットグループの作成
  13. ALBの作成
  14. ECSサービスの作成
  15. 動作確認・冗長性テスト
  16. リソース削除(クリーンアップ)
  17. 完了チェックリスト

1. アーキテクチャ概要

🌐 インターネット(エンドユーザー)
↕ HTTP 80
VPC: handson-vpc (10.0.0.0/16) / リージョン: ap-northeast-1(東京)
⚖️
ALB(handson-alb)― インターネット向け
パブリックサブネット 1a + 1c に配置 / HTTP:80 / ECSタスク2つに振り分け
↕ HTTP 8080
📦
ECS Fargate タスク ×2 — プライベートサブネット(1a・1c)
handson-subnet-private-ecs-1a (10.0.3.0/24) / handson-subnet-private-ecs-1c (10.0.4.0/24)
📦 Fargateコンテナ ⚙️ Node.js(:8080) DockerイメージはECRから取得
↕ PostgreSQL 5432
🗄️
RDS PostgreSQL 16(Multi-AZ)― プライベートサブネット(DB)
Primary: 10.0.5.0/24 (1a) / Standby: 10.0.6.0/24 (1c) / 自動フェイルオーバー
EC2版との主な違いEC2インスタンスの代わりにECS Fargateを使用します。サーバ管理(OS更新・パッチ適用)が不要になり、Dockerコンテナ単位でのデプロイ・スケーリングが可能です。アプリはECR(Elastic Container Registry)に格納したDockerイメージとして実行されます。

🔄 EC2版との構成比較

項目EC2版ECS版(本手順書)
実行環境EC2インスタンス(OS管理必要)Fargate(サーバレスコンテナ)
アプリ管理Nginx + Node.js + pm2Dockerコンテナ(Node.js:8080)
イメージ管理不要ECR(Dockerレジストリ)
スケーリングインスタンス追加タスク数変更(数秒〜数分)
接続・デバッグSession Manager(EC2接続)ECS Exec(コンテナ接続)
DB初期化psqlコマンド手動実行アプリ起動時に自動実行
ALBターゲットインスタンス型IP型(Fargate必須)

構成リソース一覧

リソース名前設定値
VPChandson-vpc10.0.0.0/16
パブリックサブネット(ALB-1a)handson-subnet-public-1a10.0.1.0/24 / ap-northeast-1a
パブリックサブネット(ALB-1c)handson-subnet-public-1c10.0.2.0/24 / ap-northeast-1c
プライベートサブネット(ECS-1a)handson-subnet-private-ecs-1a10.0.3.0/24 / ap-northeast-1a
プライベートサブネット(ECS-1c)handson-subnet-private-ecs-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 に配置 / ECSタスクのECR取得・CloudWatch用
ECR リポジトリhandson-ecrプライベートリポジトリ
ECS クラスターhandson-ecs-clusterFargate(サーバレス)
ECS タスク定義handson-task-defFargate / CPU:256 / Mem:512MB
ECS サービスhandson-ecs-serviceタスク数: 2 / プライベートサブネット配置
ALBhandson-albインターネット向け / HTTP:80
ターゲットグループhandson-tg-ecsIP型 / HTTP:8080 / ECSタスク2つ
RDShandson-rdsPostgreSQL 16 / db.t3.micro / Multi-AZ
セキュリティグループsg-alb / sg-ecs / sg-rds3つ

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

リソース概算料金備考
ECS Fargate タスク × 2(0.25vCPU / 0.5GB)約$0.02/時間タスク停止で課金なし
ALB × 1台約$0.028/時間ハンズオン後すぐ削除
RDS PostgreSQL db.t3.micro Multi-AZ約$0.052/時間必ず削除すること
NAT Gateway × 1台約$0.062/時間ECSのECR取得・CloudWatch送信に必要
ECR(ストレージ)約$0.10/GB/月数十MBのため無視できる
重要ALB・RDS・NAT Gatewayは時間課金です。ハンズオン終了後は必ず全リソースを削除してください。

2. 前提条件・事前準備

項目内容
AWSアカウントAdministratorAccess権限を持つIAMユーザー
リージョン東京(ap-northeast-1)― コンソール右上で必ず確認
ブラウザChrome / Edge / Firefox(最新版)
追加ツール不要(Dockerイメージ作成はAWS CloudShellで実施)
CloudShellとはAWSマネジメントコンソール上で使えるブラウザベースのターミナルです。AWS CLI・Docker が事前インストール済みで、追加セットアップ不要でDockerイメージのビルド・プッシュが可能です。

AWSアカウントIDの確認(手順7で使用)

コンソール右上の アカウント名 / メールアドレス をクリック → 「アカウント ID」(12桁の数字)をメモしてください。

注意アカウントIDは後の手順(ECRログイン・イメージURI)で必要です。
例: 123456789012

3. IAMロールの作成(ECSタスク実行ロール)

IAM

ECSがECRからイメージを取得し、CloudWatch Logsにログを送信するために必要なロールを作成します。

EC2版との違いEC2版では「Session Manager接続用」のロールを作成しましたが、ECS版では「ECSタスク実行ロール」を作成します。コンテナのライフサイクルはAWSが管理するため、SSMは不要です。
1
信頼されたエンティティの選択
項目
エンティティタイプAWSのサービス
ユースケースElastic Container Service(「ECS」で検索)
ユースケース(詳細)Elastic Container Service Task
次へ
2
許可ポリシーの追加

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

このポリシーが許可する操作ECRからのイメージプル、CloudWatch Logsへのログ送信など、ECSタスク実行に必要な権限が含まれています。
次へ
3
ロール名を入力して作成
項目
ロール名handson-ecs-task-execution-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-ecs-1aap-northeast-1a10.0.3.0/24ECS-1a
handson-subnet-private-ecs-1cap-northeast-1c10.0.4.0/24ECS-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つをまとめて作成し、サブネットを作成

2
パブリックサブネット 2つのパブリックIP自動割り当てを有効化(ALB用)

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

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

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

NoteECSプライベートサブネットへのパブリックIP割り当ては不要です。FargateタスクはNAT GW経由でインターネットにアクセスします。

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の役割(ECS版)プライベートサブネットのFargateタスクは、ECRからDockerイメージをプルし、CloudWatch Logsにログを送信する際にインターネット接続が必要です。NAT GWがそのアウトバウンド通信を仲介します。

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
4
ECS用プライベートルートテーブルを作成

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

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

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

送信先ターゲット
0.0.0.0/0NAT Gateway → handson-natgw
変更を保存
6
ECSプライベートサブネット 2つを関連付け

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

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

  • handson-subnet-private-ecs-1a
  • handson-subnet-private-ecs-1c
NoteDBサブネットはデフォルトのメインルートテーブル(ローカル通信のみ)を使用します。RDSはインターネットに接続しません。

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

作成順序依存関係があるため、必ず ① → ② → ③ の順に作成してください。
EC2版との違いsg-ecsのインバウンドポートが 8080 になります(EC2版は80でNginxが受信していましたが、ECS版はNode.jsが直接8080で受信します)。
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-ecs(ECS Fargateタスク用)ECS
項目
セキュリティグループ名sg-ecs
説明ECS Fargate task security group
VPChandson-vpc

インバウンドルール:

タイププロトコルポートソース説明
カスタムTCPTCP8080sg-alb のSG IDALBからのみ許可(Node.jsポート)
ポイントECS FargateではNginxを挟まないため、ALBからNode.jsの8080ポートに直接アクセスします。ALBのSGをソースに指定することでALB経由のみを許可します。
セキュリティグループを作成
3
③ sg-rds(RDS用)DB層
項目
セキュリティグループ名sg-rds
説明RDS PostgreSQL security group
VPChandson-vpc

インバウンドルール:

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

6. ECRリポジトリの作成

ECR

DockerイメージをAWS上に保存するためのプライベートリポジトリを作成します。

ECRへのアクセス方法コンソール上部の検索欄に「ECR」または「Elastic Container Registry」と入力してアクセスします。
1
リポジトリを作成
項目
可視性設定プライベート
リポジトリ名handson-ecr
タグのイミュータビリティ無効(デフォルト)
暗号化設定AES-256(デフォルト)
リポジトリを作成
URIをメモ作成後、リポジトリ一覧に表示される 「URI」 をメモしてください。次の手順で使用します。
例: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/handson-ecr

7. Dockerイメージの作成・プッシュ(CloudShell)

ECRECS

AWSコンソール上のCloudShellを使って、Node.jsアプリのDockerイメージをビルドしECRにプッシュします。

CloudShellを開く

CloudShellの特徴AWS CLI・Docker・gitが事前にインストールされています。AWSアカウントの認証情報が自動的に設定されるため、追加設定なしですぐ使えます。
1
作業ディレクトリとアプリファイルを作成
mkdir ~/handson-app && cd ~/handson-app

package.json の作成:

cat > package.json <<'EOF'
{
  "name": "handson-app",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "express": "^4.18.0",
    "pg": "^8.11.0"
  }
}
EOF
2
Node.jsアプリ(app.js)を作成
cat > app.js <<'EOF'
const express = require('express');
const { Pool } = require('pg');
const os = require('os');
const app = express();

const pool = new Pool({
  host:     process.env.DB_HOST,
  port:     5432,
  user:     process.env.DB_USER     || 'admin',
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME     || 'handson_db',
  ssl:      { rejectUnauthorized: false },
  max:      10
});

async function initDb() {
  await pool.query(`
    CREATE TABLE IF NOT EXISTS users (
      id         SERIAL PRIMARY KEY,
      name       VARCHAR(100) NOT NULL,
      email      VARCHAR(200) NOT NULL UNIQUE,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
  `);
  const { rowCount } = await pool.query('SELECT 1 FROM users LIMIT 1');
  if (rowCount === 0) {
    await pool.query(`
      INSERT INTO users (name, email) VALUES
        ('田中 太郎', 'taro@example.com'),
        ('鈴木 花子', 'hanako@example.com'),
        ('佐藤 一郎', 'ichiro@example.com')
    `);
    console.log('Sample data inserted');
  }
  console.log('DB initialized');
}

initDb().catch(err => console.error('DB init error:', err.message));

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

app.get('/', (req, res) => {
  res.json({
    message: 'ECS Fargate app is running!',
    container: os.hostname(),
    tier: 'ecs-fargate'
  });
});

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, container: os.hostname() });
  } catch (err) {
    res.status(500).json({ error: err.message, container: os.hostname() });
  }
});

app.listen(8080, () => {
  console.log('App listening on port 8080');
});
EOF
EC2版との違い環境変数(process.env.DB_HOST など)でDB接続情報を受け取ります。ハードコードせずに、ECSタスク定義で後から設定します。また、テーブル作成・サンプルデータ投入をアプリ起動時に自動実行します(initDb())。
3
Dockerfile を作成
cat > Dockerfile <<'EOF'
FROM node:20-alpine
WORKDIR /app
COPY package.json .
RUN npm install --production
COPY app.js .
EXPOSE 8080
CMD ["node", "app.js"]
EOF
4
ECRへのログイン

【AWSアカウントID】 を手順2でメモした12桁のIDに置き換えて実行します:

aws ecr get-login-password --region ap-northeast-1 | \
  docker login --username AWS --password-stdin \
  【AWSアカウントID】.dkr.ecr.ap-northeast-1.amazonaws.com

Login Succeeded と表示されれば成功です。

5
Dockerイメージをビルド・タグ付け・プッシュ

【AWSアカウントID】 を置き換えて実行します:

# イメージビルド
docker build -t handson-app .

# ECR用にタグ付け
docker tag handson-app:latest \
  【AWSアカウントID】.dkr.ecr.ap-northeast-1.amazonaws.com/handson-ecr:latest

# ECRにプッシュ
docker push \
  【AWSアカウントID】.dkr.ecr.ap-northeast-1.amazonaws.com/handson-ecr:latest

latest: digest: sha256:... と表示されれば成功です。

確認ECRコンソール → handson-ecr リポジトリ → 「イメージ」タブに latest タグのイメージが表示されることを確認します。

8. 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 を選択
作成

9. RDS PostgreSQL の作成

DB層
重要RDSの作成には約10〜15分かかります。すべての設定を確認してから「作成」をクリックしてください。
1
データベース作成方法・エンジンの選択
項目
データベース作成方法標準作成
エンジンタイプPostgreSQL
エンジンバージョンPostgreSQL 16.x(リストの最新版)
2
テンプレートと可用性の設定
項目
テンプレート開発/テスト
デプロイオプションマルチ AZ 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は削除)
アベイラビリティーゾーンap-northeast-1a(プライマリ)
7
追加設定

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

項目
最初のデータベース名handson_db
空のままにするとデータベースが作成されません。必ず入力してください。
自動バックアップを有効化チェックを外す
削除保護の有効化チェックを外す
データベースの作成
注意ステータスが 「利用可能」 になるまで10〜15分かかります。手順10〜12のECSクラスター・タスク定義・ALBの作成を進めながら待ちます。
RDS作成完了後、「エンドポイント」をメモしてください。
例: handson-rds.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com(ポート: 5432
ECS版の利点EC2版ではEC2からpsqlを実行してDBを初期化しましたが、ECS版ではアプリ(Node.js)が起動時にテーブル作成・サンプルデータ投入を自動で行います。ECSサービス起動後にALBへアクセスするだけでデータが確認できます。

10. ECSクラスターの作成

ECS

ECSタスク(コンテナ)を実行するクラスターを作成します。Fargateを使用するためEC2インスタンスの管理は不要です。

1
クラスターの設定
項目
クラスター名handson-ecs-cluster
インフラストラクチャAWS Fargate(サーバーレス)にチェックが入っていることを確認
「Amazon EC2インスタンス」はチェック不要
作成
Fargateとはコンテナ実行に必要なサーバをAWSが自動で管理します。EC2インスタンスのプロビジョニング・パッチ適用・スケーリングが不要になります。

11. ECSタスク定義の作成

ECS

コンテナの実行設定(使用するイメージ・CPU/メモリ・ポート・環境変数など)を定義します。

1
タスク定義の基本設定
項目
タスク定義ファミリーhandson-task-def
起動タイプAWS Fargate
オペレーティングシステム/アーキテクチャLinux/X86_64
タスクサイズ - CPU.25 vCPU
タスクサイズ - メモリ0.5 GB
タスクロールなし(アプリからAWSサービスを直接呼ばないため)
タスク実行ロールhandson-ecs-task-execution-role
2
コンテナの設定

「コンテナ - 1」セクションを入力します:

項目
名前handson-app
イメージ URI【AWSアカウントID】.dkr.ecr.ap-northeast-1.amazonaws.com/handson-ecr:latest
手順6でメモしたECRリポジトリのURIに「:latest」を付けたもの
コンテナポート8080
プロトコルTCP
ポート名handson-app-8080(任意)
3
環境変数の設定

「環境変数」セクションで「環境変数を追加」をクリックし、以下を入力します:

キー値タイプ
DB_HOST【RDSエンドポイント】
手順9でメモしたRDSエンドポイントを入力
DB_USERadmin
DB_PASSWORDAdminPass123!
DB_NAMEhandson_db
本番環境ではパスワードをそのまま環境変数に設定するのは避けてください。本番では AWS Secrets Manager や AWS Systems Manager Parameter Store を使用し、「値タイプ: ValueFrom」でシークレットを参照します。
4
ログ設定(CloudWatch Logs)

「ログ収集の設定」セクション:

項目
ログドライバーawslogs(デフォルトのまま)
awslogs-group/ecs/handson-task-def(自動入力)
awslogs-regionap-northeast-1
awslogs-stream-prefixecs
作成
ログ確認方法ECS版ではEC2のSSM接続でログを見る代わりに、CloudWatch Logsでコンテナのログを確認できます。
CloudWatch → 「ロググループ」→ /ecs/handson-task-def

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

ALB
ECS版の重要な違いFargateタスクはインスタンスとは異なるネットワーク構成のため、ターゲットタイプは必ず 「IP アドレス」 を選択します(「インスタンス」ではありません)。また、ポートは 8080(Node.jsのポート)を指定します。
1
ECSタスク用ターゲットグループを作成
項目
ターゲットタイプIP アドレス(Fargate必須)
ターゲットグループ名handson-tg-ecs
プロトコルHTTP
ポート8080(Node.jsが8080でリッスン)
VPChandson-vpc
プロトコルバージョンHTTP1

ヘルスチェック設定:

項目
ヘルスチェックプロトコルHTTP
ヘルスチェックパス/health
正常のしきい値2
非正常のしきい値3
間隔30 秒
次へ → IPアドレスの登録はECSサービス作成時に自動で行われるため ターゲットグループの作成
NoteEC2版ではここでEC2インスタンスを手動登録しましたが、ECS版ではECSサービス作成時にFargateタスクのIPが自動的にターゲットグループに登録・解除されます。

13. 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
3
セキュリティグループ
項目
セキュリティグループsg-alb(デフォルトのSGは削除して sg-alb のみ選択)
4
リスナーとルーティング
項目
プロトコルHTTP
ポート80
デフォルトアクションhandson-tg-ecs に転送
ロードバランサーの作成
確認作成後、ALBの「DNS 名」をメモしてください。これがアクセスURLになります。
例: handson-alb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com

14. ECSサービスの作成

ECS

ECSサービスは「タスクを常に指定数実行し続け、ALBと連携する」仕組みです。タスクが停止すると自動的に新しいタスクを起動します。

前提確認手順9のRDSが「利用可能」になってからECSサービスを作成してください。RDS作成前にECSサービスを起動するとDBへの接続に失敗します。
1
コンピューティング設定
項目
コンピューティングオプション起動タイプ
起動タイプFARGATE
プラットフォームバージョンLATEST
2
デプロイ設定
項目
アプリケーションタイプサービス
ファミリーhandson-task-def
リビジョン最新(LATEST)
サービス名handson-ecs-service
必要なタスク2(2AZに1つずつ配置)
3
ネットワーク設定
項目
VPChandson-vpc
サブネットhandson-subnet-private-ecs-1ahandson-subnet-private-ecs-1c を選択
セキュリティグループ既存のセキュリティグループを使用sg-ecs
パブリック IPオフ(無効)
プライベートサブネットのため、パブリックIPは不要
4
ロードバランサーの設定
項目
ロードバランサーのタイプApplication Load Balancer
ロードバランサー既存のロードバランサーを使用handson-alb
コンテナhandson-app 8080:8080
リスナー既存のリスナーを使用80:HTTP
ターゲットグループ既存のターゲットグループを使用handson-tg-ecs
作成
デプロイに時間がかかりますECSサービス作成後、FargateタスクがECRからイメージをプルし起動するまで約2〜5分かかります。「タスク」タブでタスクのステータスを確認してください。
5
タスク起動の確認

2つのタスクのステータスが 「RUNNING」 になっていることを確認します。

タスクが起動しない場合タスクを選択 → 「ログ」タブでエラーを確認してください。よくある原因:
① RDSエンドポイントの誤記(環境変数DB_HOST)
② RDSがまだ「利用可能」になっていない
③ セキュリティグループの設定ミス(sg-ecsのポート8080)

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

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

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

2つのFargateタスクのIPアドレスが 「healthy」 になっていることを確認します。

ターゲットの登録タイミングECS版ではECSサービスがタスク起動後に自動でターゲットグループにIPを登録します。登録からhealthyになるまで1〜2分かかります。

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

1
ALBのDNS名でアクセス

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

URL期待するレスポンス
http://【ALBのDNS名】/{"message":"ECS Fargate app is running!","container":"..."}
http://【ALBのDNS名】/health{"status":"ok","container":"..."}
http://【ALBのDNS名】/usersRDSのusersテーブルデータ(3件)
成功!データが表示されればインターネット → ALB → ECS Fargate(Node.js) → RDS PostgreSQL の動作が確認できました。
アプリが起動時にテーブル作成・サンプルデータ投入を自動で行ったため、EC2版のようなpsqlによる手動初期化は不要でした。

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

1
containerフィールドでどちらのタスクが応答しているか確認

ブラウザで /health/users に複数回アクセスすると、レスポンスの "container" フィールド(コンテナのホスト名)が2つの異なる値で切り替わることを確認します。

ECS版のホスト名EC2版の "server" フィールドはEC2のホスト名でしたが、ECS版の "container" フィールドはFargateコンテナのID(タスクARNの一部)になります。
2
フェイルオーバーテスト(オプション)

ECSコンソールでタスクを1つ「停止」すると、ECSサービスが自動的に新しいタスクを起動します。

タスクが停止されても:

  • ALBがもう一方のタスクにルーティングを切り替えるため、ブラウザからのアクセスはエラーなく継続されます
  • ECSサービスが自動的に新しいタスクを起動し、希望タスク数(2)に戻します
3
CloudWatch Logsでコンテナログを確認(オプション)

Node.jsアプリのログ(DB initializedApp listening on port 8080 など)が確認できます。

EC2版との違いEC2版ではSession Managerでサーバに接続してログを確認しましたが、ECS版はCloudWatch Logsでコンテナログを一元管理できます。

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

重要ALB・RDS・NAT Gatewayは時間課金です。ハンズオン終了後は以下の順番で必ず削除してください。
1
ECSサービスのタスク数を0に変更してからサービスを削除
項目
必要なタスク数0(タスクを全停止)
デプロイの強制チェックを入れる
更新

全タスクが停止したことを確認後 → アクション → 「サービスを削除」

Noteタスク数0に変更しないとECSサービス削除時にエラーになる場合があります。
2
ECSクラスターを削除
3
ALB を削除
4
ターゲットグループを削除
5
RDS を削除

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

6
RDS サブネットグループを削除
7
ECRイメージとリポジトリを削除

確認テキスト(delete)を入力して削除します(イメージも同時に削除されます)。

8
ECSタスク定義を無効化
NoteECSタスク定義は「削除」ではなく「登録解除(Deregister)」が正しい操作です。登録解除後、さらに「削除」ができるようになります。
9
NAT Gateway を削除

削除には数分かかります。ステータスが「削除済み」になるまで待ちます。

10
Elastic IP を解放
11
Internet Gateway をデタッチ・削除

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

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

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

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

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

14
IAMロールを削除
15
CloudWatch Logs グループを削除(オプション)

17. 完了チェックリスト

ネットワーク

セキュリティ・IAM

ECR・Docker

RDS

ECS・ALB

動作確認

クリーンアップ