冗長化構成を組み立てよう

このハンズオンでは、ALBとAuto Scalingを使った冗長化構成について実際にハンズオン形式で手を動かしながら体験します。

  • マルチAZ構成のVPCとサブネット作成
  • ALB(Application Load Balancer)の構築
  • 起動テンプレートの作成
  • Auto Scalingグループによる自動スケーリング設定
  • セキュリティグループの作成(ALB用・API用)

1. 事前準備

この講座のハンズオンでは、以下のツールやアカウントが必要です。まだ準備できていない場合は、リンク先の手順に沿って準備をお願いします。

2. ハンズオンの概要

この講座では、ALBとAuto Scalingを利用した冗長化構成を行うハンズオンを実施します。

まず、仮想ネットワークであるVPCを作成し、その内部にPublic SubnetとPrivate Subnetを2つずつ作成します。

ALBを作成し、2つのAZごとに作成した2つのPublic Subnetに展開することで、マルチAZ構成とします。

またAuto Scalingを設定し、ALBからのリクエストを処理するAPIサーバを自動で起動させます。最低2台、最大4台の範囲で稼働する設定とします。CPU使用率(平均)を監視し、70%を超えたら新しいサーバを起動させます。Auto Scalingにより起動するAPIサーバも異なるAZに分散配置し、マルチAZ構成とします。

2.1 AWS構成

以下は、このハンズオンで構築するAWS構成の全体像です。

VPC内にパブリックサブネットとプライベートサブネットを2つずつ作成し、マルチAZ構成とします。パブリックサブネットにはALBを配置してインターネットからのリクエストを受け付け、プライベートサブネットにはAuto Scalingグループで管理されるEC2インスタンスを配置します。プライベートサブネットからの外部通信はNATゲートウェイを経由します。

3. VPCの作成

3.1 VPCとネットワークリソースを一括作成

ネットワークの土台となるVPCと、関連するリソース(サブネット、インターネットゲートウェイ、NATゲートウェイ、ルートテーブル)を一括で作成します。

💡 ポイント
VPC作成時の「VPCなど」オプションを使用すると、サブネットやゲートウェイなどの関連リソースを自動で作成できます。個別リソースの詳細な作成手順については、「仮想サーバを立てよう」講座に記載があります。

AWSマネジメントコンソールで、検索ボックスからVPCを検索し、VPCダッシュボードを開きます。

左側のメニューから「お使いのVPC」を選択し、画面右上の「VPCを作成」ボタンをクリックします。

ここで、作成するリソースからVPCなどを選択してください。

そのうえで、下記内容を設定します。

設定項目 設定の基準
作成するリソース VPCなど サブネット等の関連リソースを自動作成するため
名前タグの自動生成 チェックを入れる リソース名を自動で付与するため
名前タグ my-vpc リソースを識別しやすくするため
IPv4 CIDRブロック 10.0.0.0/16 約65,000個のIPアドレスを確保でき、複数のサブネットを作成するのに十分な範囲
IPv6 CIDRブロック なし 今回はIPv4のみ使用するため
テナンシー デフォルト 特別な要件がないため
アベイラビリティゾーン(AZ)の数 2 マルチAZ構成で可用性を高めるため
パブリックサブネットの数 2 ALBを2つのAZに配置するため
プライベートサブネットの数 2 APIサーバを2つのAZに配置するため
NATゲートウェイ 1つのAZ内 プライベートサブネットからの外部通信を可能にするため(コスト削減のため1つ)
VPCエンドポイント なし 今回は使用しないため

設定が完了したら、「VPCを作成」ボタンをクリックします。

VPCサークフローの作成が行われ、しばらく経過するとステータスが「成功」となります。

3.2 リソースの確認

VPCの作成が完了すると、以下のリソースが自動的に作成されます。

リソースタイプ 自動生成される名前 用途
VPC my-vpc 仮想ネットワーク
パブリックサブネット1 my-vpc-subnet-public1-ap-northeast-1a ALB配置用(AZ-a)
パブリックサブネット2 my-vpc-subnet-public2-ap-northeast-1c ALB配置用(AZ-c)
プライベートサブネット1 my-vpc-subnet-private1-ap-northeast-1a APIサーバ配置用(AZ-a)
プライベートサブネット2 my-vpc-subnet-private2-ap-northeast-1c APIサーバ配置用(AZ-c)
インターネットゲートウェイ my-vpc-igw インターネットへの通信
NATゲートウェイ my-vpc-nat-public1-ap-northeast-1a プライベートサブネットからの外部通信
ルートテーブル(パブリック) my-vpc-rtb-public パブリックサブネット用
ルートテーブル(プライベート) my-vpc-rtb-private1-ap-northeast-1a など プライベートサブネット用

VPCダッシュボードの各メニュー(サブネット、インターネットゲートウェイ、NATゲートウェイ、ルートテーブル)を確認し、上記のリソースが作成されていることを確認してください。

💡 ポイント
「VPCなど」オプションで作成した場合、パブリックサブネットには自動的に「パブリックIPv4アドレスの自動割り当て」が有効になり、ルートテーブルも適切に設定されます。

4. セキュリティグループの作成

続いて、セキュリティグループを作成していきます。

今回は、ALBに設定するalb-sgと、APIサーバに設定するapi-sgの2つのセキュリティグループを作成していきます。

alb-sgは、インバウンドルールとしてすべてのソース(0.0.0.0/0)からのHTTP通信を許可します。

api-sgは、alb-sgからのHTTP通信を許可します。これにより、ALB以外からの通信を拒絶することができます。

また、どちらもアウトバウンドルールは、すべてのトラフィック通信を許可します。

名前 インバウンドルール アウトバウンドルール 設定の基準
alb-sg HTTP (80) / 0.0.0.0/0 すべてのトラフィック / 0.0.0.0/0 インターネットからのHTTPアクセスを受け付ける
api-sg HTTP (80) / alb-sg すべてのトラフィック / 0.0.0.0/0 ALBからのHTTPアクセスのみを許可しセキュリティを確保

VPCダッシュボードの左側メニューから「セキュリティグループ」を選択します。

4.1 ALBのセキュリティグループ

まずはALBのセキュリティグループを作成していきます。

セキュリティグループの作成

画面右上の「セキュリティグループを作成」ボタンをクリックします。

下記の内容を設定してください。

設定項目 設定の基準
セキュリティグループ名 alb-sg リソースを識別しやすくするため
説明 Security group for ALB セキュリティグループの用途を明記するため
VPC my-vpc-vpc 作成したVPCに関連付けるため

インバウンドルールの設定

「インバウンドルール」セクションで「ルールを追加」ボタンをクリックし、下記の内容を設定してください。

設定項目 設定の基準
タイプ HTTP HTTPプロトコルでの通信を許可するため
ソース Anywhere-IPv4(0.0.0.0/0) インターネットからのアクセスを許可するため

アウトバウンドルールはデフォルトで「すべてのトラフィックを許可」が設定されているため、変更は不要です。

設定が完了したら、「セキュリティグループを作成」ボタンをクリックします。

リソースの確認

セキュリティグループ一覧に戻り、alb-sgを選択します。インバウンドルールに、タイプがHTTP、ソースが0.0.0.0/0のルールが設定されていることを確認してください。

4.2 APIのセキュリティグループ

セキュリティグループの作成

セキュリティグループ一覧に戻り、再度「セキュリティグループを作成」ボタンをクリックします。

下記の内容を設定してください。

設定項目 設定の基準
セキュリティグループ名 api-sg リソースを識別しやすくするため
説明 Security group for API セキュリティグループの用途を明記するため
VPC my-vpc-vpc 作成したVPCに関連付けるため

インバウンドルールの設定

「インバウンドルール」セクションで「ルールを追加」ボタンをクリックし、下記の内容を設定してください。

設定項目 設定の基準
タイプ HTTP HTTPプロトコルでの通信を許可するため
ソース カスタム → alb-sg ALBからの通信のみを許可するため

ソースの設定では、「カスタム」を選択した後、検索ボックスに「alb-sg」と入力すると、先ほど作成したセキュリティグループが表示されるので、それを選択してください。

アウトバウンドルールはデフォルトで「すべてのトラフィックを許可」が設定されているため、変更は不要です。

設定が完了したら、「セキュリティグループを作成」ボタンをクリックします。

リソースの確認

セキュリティグループ一覧に戻り、api-sgを選択します。インバウンドルールに、タイプがHTTP、ソースがalb-sgのルールが設定されていることを確認してください。

5. Application Load Balancerの作成

続いてALB(Application Load Balancer)の作成を行っていきます。

5.1 ターゲットグループを作成

まずは、ALBにて、転送先となるEC2インスタンスを指定するための「ターゲットグループ」を作成していきます。

EC2ダッシュボードの左メニューにある「ロードバランシング」セクションから「ターゲットグループ」を選択し、画面右上の「ターゲットグループの作成」ボタンをクリックします。

設定画面では、まずターゲットタイプとして「インスタンス」を選択してください。

次に「ターゲットグループ名」に api-tg と入力します。

プロトコルは「HTTP」とし「80」としてください。これは、一般的なHTTPプロトコルで通信する場合のプロトコルとポートです。

VPCは、今回作成した my-vpc-vpc を選択してください。

続いて「ヘルスチェック」の設定項目を確認します。ロードバランサーがサーバの生存確認を行うための設定です。プロトコルは「HTTP」のまま、ヘルスチェックパスをデフォルトの「/」から /health に変更してください。これはアプリケーション側で用意されているヘルスチェック専用のパスです。

それ以外の項目はデフォルトで構いませんので、「次へ」をクリックします。

「ターゲットの登録」画面が表示されますが、現時点ではまだインスタンスを登録しないため、何も選択せずにそのまま画面下の「次へ」ボタンをクリックしてください。インスタンスはこの後オートスケーリングにより作成するため、この後の設定で、オートスケーリングで作ったインスタンスが登録されるようにします。

確認画面が表示されるので、入力内容に問題がなければ「ターゲットグループの作成」をクリックします。

⚠️ ターゲットグループのヘルスチェックが「unhealthy」になる場合
ヘルスチェックパスに指定したエンドポイント(/healthなど)が、アプリケーション側で実装されているか確認してください。
また、セキュリティグループでALBからEC2への通信(HTTP 80番ポート)が許可されているか確認してください。

無事にapi-tgが作成されれば、ここまでの操作はOKです。

5.2 ALBを作成

続いて、ALBの作成を行っていきます。

まず、EC2のダッシュボードを開き、左側のメニューにある「ロードバランサー」をクリックします。

画面上の「ロードバランサーの作成」ボタンを押します。

種類の選択画面が表示されるので、「Application Load Balancer」の欄にある「作成」を選んで設定画面へ進んでください。

設定画面では、最初に基本的な構成を入力します。ロードバランサー名として「api-alb」と入力し、外部からのアクセスを受け付けるためスキームは「インターネット向け」、IPアドレスタイプは「IPv4」が選択されている状態にします。

次にネットワークマッピングの設定を行います。VPCの項目で今回作成した「my-vpc-vpc」を選択した後、アベイラビリティゾーンの指定を行います。「ap-northeast-1a」にチェックを入れて対応する「my-vpc-subnet-public1-ap-northeast-1a」を選び、続いて「ap-northeast-1c」にもチェックを入れて「my-vpc-subnet-public2-ap-northeast-1c」を選ぶことで、異なる2つのゾーンのパブリックサブネットを割り当てます。

続いてセキュリティグループの設定箇所では、デフォルトで選択されているグループのチェックを外し、作成済みのALB用セキュリティグループである「alb-sg」だけを選択し直します。

最後にリスナーとルーティングの設定を確認します。プロトコルが「HTTP」、ポートが「80」になっていることを確認し、デフォルトアクションの転送先として、直前の手順で作成したターゲットグループ「api-tg」を指定してください。

CloudFront、WAF、Global Acceleratorなどを一緒に設定することもできますが、今回はひとまず不要とします。

ここまでの設定に間違いがないことを確認し、画面最下部の「ロードバランサーの作成」ボタンをクリックして構築を完了します。

⚠️ ALBの作成に失敗する場合
選択したサブネットが異なるアベイラビリティゾーンにあることを確認してください。ALBは最低2つの異なるAZにまたがるサブネットが必要です。
また、サブネットがパブリックサブネット(インターネットゲートウェイへのルートがある)であることを確認してください。

無事にapi-albが作成されれば、ここまでの操作は完了です。

6. Auto Scalingグループの作成

続いて、Auto Scalingグループの作成を行っていきます。

6.1 起動テンプレートを作成

オートスケーリングの前処理として、EC2インスタンスの起動方法を示す「起動テンプレート」を作成していきます。

EC2ダッシュボードの左側にあるメニューから「起動テンプレート」を選択し、画面上の「起動テンプレートを作成」ボタンをクリックして設定画面を開いてください。

まず基本設定として、起動テンプレート名に api-template と入力し、テンプレートバージョンの説明欄には Initial version と記述します。

次に、Amazon マシンイメージ (AMI) のセクションでは「Amazon Linux 2023 AMI」を選択します。

インスタンスタイプには t3.micro を指定してください。

キーペア(ログイン)の項目では、「仮想サーバを立てよう」のハンズオンで作成したmy-keyが残っていればそれを選択、ない場合は新しいキーペアを作成してください。

続いてネットワーク設定のセクションを設定します。サブネット及びアベイラビリティゾーンは、マルチAZとなるように自動設定したいので、ここでは「起動テンプレートの設定に含めない」を指定します。セキュリティグループの設定は、「既存のセキュリティグループを選択する」をチェックし、api-sg を選択してください。

ストレージ及びリソースタグは設定不要です。

最後に、画面下部の「高度な詳細」セクションを展開し、一番下にある「ユーザデータ」というテキストボックスを探します。

以下のスクリプトを貼り付けてください:

#!/bin/bash
set -e

# Update system
dnf update -y

# Install Go
dnf install -y golang

# Set Go environment variables
export HOME=/root
export GOPATH=/root/go
export GOMODCACHE=/root/go/pkg/mod
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin

# Create app directory
mkdir -p /opt/api
cd /opt/api

# Create the API application
cat > main.go << 'GOEOF'
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

type Response struct {
    Message string `json:"message"`
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
    result := Response{Message: "API接続に成功しました"}
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(result)
}

func main() {
    http.HandleFunc("/health", healthHandler)

    fmt.Println("Starting API server on port 80...")
    log.Fatal(http.ListenAndServe(":80", nil))
}
GOEOF

# Initialize Go module
go mod init api-server
go mod tidy

# Build the application
go build -o api-server main.go

# Create systemd service
cat > /etc/systemd/system/api-server.service << SERVICEEOF
[Unit]
Description=API Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/api
ExecStart=/opt/api/api-server
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
SERVICEEOF

# Enable and start service
systemctl daemon-reload
systemctl enable api-server
systemctl start api-server

貼り付けが終わったら設定内容を再確認し、画面右下の「起動テンプレートを作成」ボタンをクリックして完了です。

⚠️ ユーザデータのスクリプトが実行されない場合
スクリプトの先頭に#!/bin/bashが記載されているか確認してください。
また、EC2インスタンスにSSHでログインし、/var/log/cloud-init-output.logを確認するとエラーの詳細がわかります。
プライベートサブネットの場合、NATゲートウェイが正しく設定されていないとパッケージのダウンロードに失敗します。

6.2 Auto Scalingグループを作成

最後に、負荷に応じてサーバの台数を自動で調整する「Auto Scaling グループ」を作成し、システム全体の自律的な運用を実現します。

EC2ダッシュボードの左メニューから「Auto Scaling グループ」を選択します。

画面右上の「Auto Scaling グループの作成」ボタンをクリックしてウィザードを開始してください。

最初のステップでは、グループの名前と使用するテンプレートを指定します。Auto Scaling グループ名に api-auto-scaling と入力し、起動テンプレートのプルダウンメニューから、先ほど作成した api-template を選択します。また、バージョンはLatest(1)に変更しておくことで、今後起動テンプレートを変更したとき、自動で最新版に更新し直してくれます。この状態で次へ進みます。

続いてネットワークの設定を行います。VPCには my-vpc-vpc を選択し、アベイラビリティゾーンとサブネットの項目では、APIサーバを配置するプライベートサブネットである my-vpc-subnet-private1-ap-northeast-1amy-vpc-subnet-private2-ap-northeast-1c の2つを確実に選択してください。

次のステップはロードバランサーとの連携設定です。「既存のロードバランサーにアタッチ」を選択し、「既存のロードバランサーターゲットグループ」のリストから api-tg を指定します。

VPC Lattice 統合オプションやApplication Recovery Controller (ARC) のゾーンシフトは今回利用しないため、設定不要です。

また、ヘルスチェックのオプションでは「Elastic Load Balancing のヘルスチェックをオンにする」にチェックを入れてください。これにより、ロードバランサーが異常を検知した際に、自動的にインスタンスの入れ替えが行われるようになります。

チェックが終わったら「次へ」をクリックしてください。

最後に、グループのサイズとスケーリングポリシーを設定します。「希望するキャパシティ」と「最小容量」をそれぞれ 2 に設定して冗長性を確保し、「最大容量」は 4 に設定して急激なアクセス増に備えます。さらに「ターゲット追跡スケーリングポリシー」を選択し、メトリクスタイプを「平均 CPU 使用率」、ターゲット値を 70 に設定してください。これにより、CPU使用率が70%を超えると自動でサーバが増える仕組みになります。

すべての設定を確認したら、画面下の「次へ」をクリックして完了です。

「通知を設定する」の項目ですが、今回は特に通知設定を行わないため、何も設定せず「次へ」をクリックしてください。

タグについても今回は特に設定しないため、「次へ」をクリックします。

確認画面が表示されるので、内容に問題がなければ「Auto Scalingグループを作成する」をクリックします。

⚠️ Auto Scalingでインスタンスが起動しない場合
EC2ダッシュボードの「Auto Scalingグループ」→「アクティビティ」タブでエラーメッセージを確認してください。よくある原因として、
(1) 起動テンプレートで指定したセキュリティグループやサブネットが削除されている
(2) インスタンスタイプの在庫不足
(3) IAMロールの権限不足
などがあります。

無事にapi-auto-scalingが作成されていれば、ここまでの操作は完了です。

7. 動作確認

7.1 EC2インスタンスの起動確認

まずは、Auto ScalingによりEC2インスタンスが自動で起動されていることを確認します。

EC2のダッシュボードから、左側のインスタンスをクリックして、EC2インスタンスの一覧を開きます。

一覧の中に新しいEC2インスタンスが2つ起動していることを確認してください。

7.2 ターゲットグループの確認

続いて、ターゲットグループのターゲットとしてEC2インスタンスが設定されているかを確認します。

まず、EC2のダッシュボードからターゲットグループを選択し、api-tgを開きます。

その中でまず、正常となっている箇所に2と数字が記載されていることを確認します。これは、2つのインスタンスが、このターゲットグループに正常に紐づいていることを意味します。もし紐づいていない場合はここにカウントされません。

また、異常が発生している場合は、異常の部分に数字がカウントされます。

💡 ポイント
EC2インスタンスを起動した直後は、ヘルスチェックが完了するまで「異常」や「Initial(初期化中)」と表示されることがあります。数十秒〜数分ほど待ってから再度確認すると「正常」に変わりますので、すぐに異常が表示されても慌てずにお待ちください。

次に、「登録済みターゲット」の部分に、2件のEC2インスタンスが設定されていることを確認します。これによっても、2件のEC2インスタンスがターゲットとして登録されていることを確認できます。

7.3 ロードバランサーの確認

続いて、ロードバランサーの設定を確認します。

EC2のダッシュボードからロードバランサーを選択し、api-albを開きます。そこでリソースマップのタブを開くと、リスナーからルール、ターゲットグループ、ターゲット(EC2インスタンス)までのリソースの構成が可視化されます。ここで、正しく線が繋がっており、ターゲット2件が「正常」となっていることを確認します。

なお、リスナーから正しく通信できていない場合は、「異常」と表示されます。

7.4 ロードバランサー経由でのアクセス確認

最後に、ロードバランサー経由でアプリケーションにアクセスできるかを確認します。

api-albを開きDNS名の部分をコピーします。

このDNS名を使って、Windowsの場合はコマンドプロンプト、Macの場合はターミナルを開き、curlコマンドによりAPIを呼び出します。<DNS名>の部分を、コピーしたDNS名に置き換えてください。

curl http://<DNS名>/health

以下のように、メッセージが表示されれば、無事にAPIが実行されています。

{"message":"API接続に成功しました"}
⚠️ curlでALBにアクセスできない場合
(1) ALBのセキュリティグループで、インターネットからのHTTP(80番ポート)が許可されているか確認
(2) ターゲットグループの「ターゲット」タブで、インスタンスのステータスが「healthy」になっているか確認
(3) EC2インスタンスでアプリケーションが正常に起動しているか確認してください。
503 Service Temporarily Unavailableが表示される場合は、ターゲットが1つも健全でないことを示しています。

8. リソースの削除

最後に、構築した環境をきれいに削除し、不要なコストが発生しないように後片付けを行います。AWSのリソースには削除の順序(依存関係)があり、順番を間違えるとエラーになることがあるため、以下の流れに沿って確実に削除を進めてください。

まず、Auto Scaling グループの削除から始めます。EC2コンソールの「Auto Scaling グループ」画面で api-auto-scaling を選択し、アクション > 削除を実行してください。

オートスケーリンググループを削除することで、グループによって管理されていたEC2インスタンスが自動的に「終了(Terminated)」状態へと移行します。なお、オートスケーリンググループの削除には少し時間がかかります。

続いて、起動テンプレートを削除します。起動テンプレートのメニューを開き、api-templateをチェックして、アクション > テンプレートを削除を選択してください。

次に、ロードバランサーを削除します。ロードバランサーメニューからapi-albをチェックし、アクション > ロードバランサーの削除を行ってください。

続いてターゲットグループを削除します。ターゲットグループのメニューを開き、api-tgをチェックしたうえで、アクション > 削除を行います。

続いて、NATゲートウェイを削除します。VPCのダッシュボードから、NATゲートウェイのメニューを開き、my-vpc-nat-poublic1-ap-northeast-1aをチェックしたうえで、アクション > NATゲートウェイを削除、を行います。なお、NATゲートウェイの削除には少し時間がかかります。

最後に、VPCを削除します。VPCダッシュボードの「お使いのVPC」メニューを開き、my-vpcをチェックの上、アクション > VPCの削除を行います。

💡 ポイント
「VPCなど」オプションで作成した場合、VPCを削除すると、サブネット、インターネットゲートウェイ、NATゲートウェイ、ルートテーブル、Elastic IPなどの関連リソースも一緒に削除されます。

9. まとめ

このハンズオンでは、ALBとAuto Scalingを利用した冗長化構成の構築を体験しました。

  • マルチAZ構成により、1つのAZで障害が発生しても別のAZでサービスを継続できる
  • ALB(Application Load Balancer)は複数のAZにまたがって配置され、トラフィックを分散する
  • Auto Scalingにより、負荷に応じてEC2インスタンスの台数を自動で調整できる
  • ターゲットグループでヘルスチェックを行い、異常なインスタンスを自動で除外する
  • セキュリティグループでALBからAPIサーバへの通信のみを許可し、セキュリティを確保する