【AWSハンズオン】第3回 Application Load Balancer構築

【AWSハンズオン】第3回 Application Load Balancer構築

前回構築したセキュリティ基盤の上に、Application Load Balancer (ALB)を構築します。インターネットからのトラフィックを受け付け、後続のECSコンテナに転送する仕組みを実装しましょう。

AWS #AWS#ハンズオン#初学者向け

【AWSハンズオン】第3回 Application Load Balancer構築

サムネイル

前回構築したセキュリティ基盤の上に、Application Load Balancer (ALB)を構築します。インターネットからのトラフィックを受け付け、後続のECSコンテナに転送する仕組みを実装しましょう。

更新日: 8/11/2025

今回作業対象のブランチ

前提条件

  • 第1回のVPCネットワーク基盤構築が完了していること
  • 第2回のセキュリティとNAT Gateway設定が完了していること
  • こちらからDockerコンテナでの実行環境が準備できていること

Terraform実行環境の起動

前回と同様に、Dockerコンテナ内で作業を進めます。

# コンテナを起動してbashに入る
docker-compose run --rm terraform

これ以降のコマンドは、すべてこのコンテナ内で実行します。

基礎的な知識

Application Load Balancer (ALB)は、アプリケーション層(レイヤー7)で動作するロードバランサーです。HTTPやHTTPSトラフィックを複数のターゲットに分散します。

WEBアプリケーション開発者の視点から見ると

  • Nginxやリバースプロキシの役割をクラウドで自動化したサービスです
  • ローカル開発ではlocalhost:3000に直接アクセスしますが、本番環境では複数のサーバーインスタンスが動いています
  • ALBが「どのサーバーにリクエストを送るか」を自動で判断します

主な機能

  • 負荷分散: 複数のターゲットに均等にリクエストを分散
  • ヘルスチェック: 異常なターゲットを自動で切り離し
  • SSL終端: HTTPS通信の暗号化・復号化を処理
  • パスベースルーティング: URLパスに応じて異なるターゲットグループに転送

Target Groupとは

Target Groupは、ALBがトラフィックを転送する先の論理的なグループです。ECSタスク、EC2インスタンス、Lambda関数などを登録できます。

Target Groupの種類

ターゲットタイプ 用途 今回の使用
instance EC2インスタンス用 -
ip IPアドレス指定(Fargate用) ⚪︎
lambda Lambda関数用 -

ECS Fargateではawsvpcネットワークモードを使用するため、ipタイプのTarget Groupを作成します。

Listenerとは

Listenerは、ALBがどのポートでどのプロトコルのリクエストを受け付けるかを定義します。受信したリクエストを適切なTarget Groupに転送するルールも設定します。

基本的なListener設定

  • プロトコル: HTTP (ポート80) / HTTPS (ポート443)
  • デフォルトアクション: リクエストの転送先Target Group
  • ルール: パスやホストベースの詳細なルーティング

今回作成するネットワーク構成

リソース 説明 数量
Application Load Balancer インターネット向けロードバランサー 1個
Target Group (IP type) ECS Fargate用のターゲットグループ 1個
Listener (HTTP) ポート80でのHTTPリクエスト受付 1個
Listener Rule デフォルトルール(すべてのトラフィックを転送) 1個

ネットワークフロー

  1. インターネット → ALB: ユーザーのHTTPリクエスト
  2. ALB → Target Group: ヘルスチェック、リクエスト転送
  3. Target Group → ECS: 登録されたタスクへのトラフィック分散

Terraformコードの実装

Application Load Balancer

インターネット向けのALBをパブリックサブネットに作成します。

# terraform/alb.tf

# Application Load Balancer
resource "aws_lb" "main" {
  name               = "${var.project_name}-${var.environment}-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = aws_subnet.public[*].id

  enable_deletion_protection = false  # 開発環境では削除を許可

  # ALBアクセスログの設定(オプション)
  # access_logs {
  #   bucket  = aws_s3_bucket.alb_logs.id
  #   prefix  = "alb-access-logs"
  #   enabled = true
  # }

  tags = {
    Name = "${var.project_name}-${var.environment}-alb"
  }
}

Target Group

ECS Fargate用のTarget Groupを作成します。IPタイプを指定し、ヘルスチェックを設定します。

# terraform/alb.tf

# Target Group for ECS Fargate
resource "aws_lb_target_group" "ecs" {
  name        = "${var.project_name}-${var.environment}-ecs-tg"
  port        = 3000
  protocol    = "HTTP"
  vpc_id      = aws_vpc.main.id
  target_type = "ip"

  # ヘルスチェック設定
  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30
    matcher             = "200"
    path                = "/health"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = 5
    unhealthy_threshold = 2
  }

  # ECSサービスが削除される前にターゲットの登録解除を待つ
  deregistration_delay = 60

  tags = {
    Name = "${var.project_name}-${var.environment}-ecs-tg"
  }
}

ヘルスチェックパスについて

今回は/healthエンドポイントでヘルスチェックを行う設定にしています。後でHonoアプリケーションを作成する際に、この/healthエンドポイントを実装する必要があります。

Listener

HTTP (ポート80) でリクエストを受け付け、Target Groupに転送するListenerを作成します。

# terraform/alb.tf

# HTTP Listener
resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.main.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.ecs.arn
  }

  tags = {
    Name = "${var.project_name}-${var.environment}-http-listener"
  }
}

HTTPS Listenerについて

本番環境では通常HTTPS Listenerも作成しますが、今回は学習目的のためHTTPのみとします。HTTPS化する場合は、Certificate ManagerでSSL証明書を取得し、HTTPS Listener (ポート443) を追加する必要があります。

出力の更新

作成したALBリソースの情報をterraform/outputs.tfに追加します。

# terraform/outputs.tf(既存の出力に追加)

# ALB関連の出力
output "alb_arn" {
  description = "ALB ARN"
  value       = aws_lb.main.arn
}

output "alb_dns_name" {
  description = "ALB DNS名"
  value       = aws_lb.main.dns_name
}

output "alb_zone_id" {
  description = "ALB Zone ID"
  value       = aws_lb.main.zone_id
}

output "target_group_arn" {
  description = "Target Group ARN"
  value       = aws_lb_target_group.ecs.arn
}

output "alb_security_group_id" {
  description = "ALB Security Group ID(参照用)"
  value       = aws_security_group.alb.id
}

リソースを作成

Dockerコンテナ内で以下のコマンドを実行します。

# terraformディレクトリへ移動
cd terraform

# 実行計画の確認
terraform plan

# リソースの作成
terraform apply

ALBの作成には2〜3分程度かかります。

作成結果の確認

# ALB DNS名の確認(重要:動作確認で使用)
terraform output alb_dns_name

# Target Group ARNの確認
terraform output target_group_arn

# ALB ARNの確認
terraform output alb_arn

alb_dns_nameの出力例

my-project-dev-alb-1234567890.ap-northeast-1.elb.amazonaws.com

動作確認

AWS Management Consoleでの確認

EC2 > ロードバランサー

作成されたALBを選択し、以下を確認します

カテゴリ 項目 設定値
基本設定 スキーム internet-facing
IPアドレスタイプ ipv4
VPC 作成したVPC
アベイラビリティゾーン 2つのパブリックサブネット
セキュリティ セキュリティグループ ALB用Security Group
許可されたトラフィック HTTP (80), HTTPS (443)

EC2 > ターゲットグループ

作成されたTarget Groupを選択し、以下を確認します

カテゴリ 項目 設定値
基本設定 ターゲットタイプ IP
プロトコル HTTP:3000
VPC 作成したVPC
ヘルスチェック プロトコル HTTP
パス /health
正常のしきい値 2
非正常のしきい値 2
ターゲット 登録ターゲット 現時点では登録されたターゲットはありません(ECSタスクが未作成のため)

ALB DNS名での疎通確認

DNS名の取得方法

TerraformでALBのDNS名を取得するには、以下のコマンドを使用します

# ALB DNS名を取得
terraform output alb_dns_name

または、出力値を直接変数として使用する場合

# DNS名を変数に格納
ALB_DNS=$(terraform output -raw alb_dns_name)
echo "ALB DNS名: $ALB_DNS"

疎通確認の実行

現在はまだECSタスクが存在しないため、ALBにアクセスしても503エラーが返されます。これは正常な動作です。

# TerraformでDNS名を取得してからアクセス
ALB_DNS=$(terraform output -raw alb_dns_name)
curl -v http://$ALB_DNS

または、DNS名を直接指定してアクセス

# curlでALBにアクセス(503エラーが返される)
curl -v http://[ALB_DNS_NAME]

実際のアクセス例

curl -v http://my-project-dev-alb-1234567890.ap-northeast-1.elb.amazonaws.com

期待される結果

< HTTP/1.1 503 Service Temporarily Unavailable
< Server: awselb/2.0
< Date: Wed, 23 Jul 2025 11:56:48 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
</body>
</html>

この503エラーは、Target Groupにターゲットが登録されていないため発生します。次回ECSタスクを作成・登録すると、正常にレスポンスが返されるようになります。

ALBのコスト管理

ALB(Application Load Balancer)は時間あたりの固定料金とLCU(Load Balancer Capacity Unit)に基づく従量課金が発生します。

料金体系

項目 料金
固定料金 約$0.0225/時間(東京リージョン)
LCU料金 約$0.008/LCU・時間

開発・学習用途では、使用しない時間帯はterraform destroyでリソースを削除することでコストを削減できます。

# 不要な場合はリソースを削除
terraform destroy

ALB削除時の注意点

ALBを削除すると、DNS名も変更されます。再作成時は新しいDNS名が割り当てられるため、アプリケーション側の設定更新が必要になる場合があります。

次のステップ

次回は、ECSクラスターとIAMロールを設定します。作成したTarget GroupにECSタスクを登録し、ALB経由でアプリケーションにアクセスできるようにします。

  • ECSクラスターの作成
  • ECS Task Role、Execution Roleの設定
  • ECRリポジトリの準備
  • 権限設定の動作確認

検索

検索条件に一致する記事が見つかりませんでした