0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS CDKでNext.jsを本番構成にする【第1回】〜VPC構成とネットワーク設計〜

0
Last updated at Posted at 2026-03-17

はじめに

前シリーズ「AWS CDKでNext.jsをデプロイする」では、次の構成を作成しました。

  • ECR:コンテナイメージ保存
  • ECS(Fargate):アプリ実行
  • ALB:外部公開
  • ECS Service:タスク常時稼働
  • Security Group:通信制御

これにより、Next.jsアプリをAWS上で公開する最小構成が完成しました。

ただし、この構成は検証用のシンプルな構成です。
実際の本番環境では、VPCを利用してネットワークを分離する構成が一般的です。

例えば次のような構成です。

  • 専用VPCを作成する
  • Public SubnetとPrivate Subnetを分離する
  • アプリケーションはPrivate Subnetに配置する

本記事では、この 本番環境を想定した VPC 構成 を AWS CDK で構築していきます。

本シリーズの構成

1. PC構成編(本記事)
2. Route53独自ドメイン設定編
3. ACM HTTPS化編
4. WAFセキュリティ編
5. ECS Auto Scaling編
6. CI/CD構築編

VPC構成

※ALB(Application Load Balancer)は、論理的には1つのリソースですが、実際には複数AZのPublic Subnetにまたがって配置されます。

本番環境では、VPC内部をPublic SubnetとPrivate Subnetに分ける構成が一般的です。

ALBはインターネットからのリクエストを受け付け、Target Groupを通じて複数のECSタスクへ分散します。
また、クロスAZでトラフィックを分散するため、異なるAZに配置されたECSタスクへもルーティングされます。

一方で、ECS(Fargate)は各AZのPrivate Subnet上に配置されます。
これにより、ECSタスクはインターネットから直接アクセスできず、ALB経由の通信のみを受け付ける構成となります。

本番ではECSタスクは複数稼働させます。
(AZ障害対策・負荷分散・無停止デプロイ)

図ではこの本番構成(複数タスク・複数AZ)を示しています。

本記事ではネットワーク構成にフォーカスし、desiredCountやAutoScalingの設定は 第5回「ECS Auto Scaling を設定する」 で解説します。

Private Subnetは外部へ直接アクセスできないため、ECRのイメージ取得や外部API呼び出しは
通常はNAT Gatewayを経由して行われます。
(VPC Endpointを利用することでNATを経由しない構成も可能です)

また、VPC 作成時にはサブネットごとにルートテーブルが自動作成され、次のように設定されます。

  • Public Subnet:0.0.0.0/0 → Internet Gateway
  • Private Subnet:0.0.0.0/0 → NAT Gateway

ネットワーク設計のポイント

本記事で採用している構成には、いくつかの設計意図があります。

  • インターネットからの入口はALBのみに限定する
  • アプリケーションはPrivate Subnetに配置し、直接アクセスを防ぐ
  • 外部通信はNAT Gateway経由に制限する
  • 可用性向上のため、複数AZにリソースを分散する

これにより、

  • セキュリティ(外部からの直接アクセス遮断)
  • 可用性(AZ障害耐性)
  • 運用性(通信経路の明確化)

をバランスよく満たす構成となります。

インフラ設計(VPCをNetworkStackとして分離する)

VPCはネットワーク基盤のため、アプリケーションStackとは分離して管理します。

今回のStack構成は次の通りです。

NetworkStack
 └ VPC

EcsStack
 └ ECS Cluster
 
AlbStack
 └ ALB

ServiceStack
 └ ECS Service

依存関係は次のようになります。

NetworkStack
   ↓       ↓
AlbStack  EcsStack
      ↓     ↓
     ServiceStack

ALBとECSはどちらもVPCに依存しており、ECS ServiceはALBのTarget GroupおよびECS Clusterの両方に依存する構成になります。


1-1. NetworkStack(VPC作成)

VPCを作成するStackを作成します。

lib/network-stack.ts

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class NetworkStack extends cdk.Stack {

  public readonly vpc: ec2.Vpc;

  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    this.vpc = new ec2.Vpc(this, 'AppVpc', {
      maxAzs: 2,
      natGateways: 2, 
    });

  }
}

この設定により次のリソースが作成されます。

  • Public Subnet ×2
  • Private Subnet ×2
  • NAT Gateway ×2

本番環境では、各AZに NAT Gatewayを1台ずつ配置する構成が推奨されます。

理由:
NAT Gateway は AZ障害時にフェイルオーバーしない
クロスAZ通信は遅延・料金増につながる
Private Subnet のタスク(ECS)は同じAZ内のNATにルーティングされるのが正しい

1-2. EcsStack

NetworkStackで作成したVPCを利用します。

lib/ecs-stack.ts

interface EcsStackProps extends cdk.StackProps {
  vpc: ec2.IVpc;
}

export class EcsStack extends cdk.Stack {

  public readonly cluster: ecs.Cluster;

  constructor(scope: Construct, id: string, props: EcsStackProps) {
    super(scope, id, props);

    this.cluster = new ecs.Cluster(this, 'NextjsCluster', {
      vpc: props.vpc,
    });

    //...

  }
}

1-3. ServiceStack(Private Subnet配置)

ECS Serviceは Private Subnet に配置します。

lib/service-stack.ts

assignPublicIp: false,
vpcSubnets: {
  subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
}

1-4. bin配下のtsファイルを修正する

#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { EcrStack } from '../lib/ecr-stack';
import { NetworkStack } from '../lib/network-stack';
import { EcsStack } from '../lib/ecs-stack';
import { AlbStack } from '../lib/alb-stack';
import { ServiceStack } from '../lib/service-stack';

const app = new cdk.App();

const env = {
  account: process.env.CDK_DEFAULT_ACCOUNT,
  region: process.env.CDK_DEFAULT_REGION,
};

new EcrStack(app, 'NextjsEcrStack', {
  env
});

const networkStack = new NetworkStack(app, 'NextjsNetworkStack', {
  env,
});

const ecsStack = new EcsStack(app, 'NextjsEcsStack', {
  env,
  vpc: networkStack.vpc,
});

const albStack = new AlbStack(app, 'NextjsAlbStack', {
  env,
  vpc: networkStack.vpc,
});

new ServiceStack(app, 'NextjsServiceStack', {
  env,
  cluster: ecsStack.cluster,
  taskDefinition: ecsStack.taskDefinition,
  targetGroup: albStack.targetGroup,
  vpc: networkStack.vpc,
  albSecurityGroup: albStack.albSecurityGroup,
});

1-5. デプロイ

この記事は、前シリーズで作成した環境がすでに存在している前提で進めます。

前シリーズで準備した構成:

  • ECR(リポジトリ + イメージ)
  • ECS Cluster / Task Definition
  • ALB / Target Group
  • ECS Service

もし未構築の場合は、前シリーズを実施するか、同等の構成をあらかじめ準備したうえで進めてください。

デフォルトVPCから専用VPCに移行する場合の注意点

今回の構成では新しいVPCを作成するため、
既存の ALB / ECS / ECS Service がデフォルトVPCに紐づいている場合は
そのまま更新できないケースがあります。

その場合は、以下の「既存Stack削除」を実施してから再デプロイしてください。

1. 既存Stack削除(移行時のみ)

cdk destroy NextjsServiceStack NextjsAlbStack NextjsEcsStack --profile <プロファイル名>

※ ECRまで作り直す必要はなく、通常はそのまま利用できます。
※ 新規環境の場合は、destroyは不要です。

2. デプロイ

cdk deploy NextjsServiceStack --profile <プロファイル名>

ServiceStackが依存している以下のStackも自動的にデプロイされます。

  • NetworkStack
  • EcsStack
  • AlbStack

AWSコンソールで確認

VPC

1.AWSコンソール → VPC を開く
2.左メニュー → 「お使いのVPC」をクリック
3.作成したVPC(vpc-xxxx)をクリック
4.「リソースマップ」タブを開く

以下を確認します。

  • Public Subnet が2つ存在する
  • Private Subnet が2つ存在する

また、それぞれのサブネットをクリックし、詳細画面で以下を確認します。

Public Subnet

  • パブリック IPv4 アドレスを自動割り当て → はい

Private Subnet

  • パブリック IPv4 アドレスを自動割り当て → いいえ

ECS

1.AWSコンソール → ECS を開く
2.クラスター → 作成されたクラスター → タスクタブ → 対象のタスクをクリック
3.「設定」セクションで以下を確認します。

  • サブネット → subnet-xxxx
  • パブリック IP → -
  • プライベート IP → 10.x.x.x

次に、サブネットのリンク(subnet-xxxx)をクリックし、サブネット詳細画面で以下を確認します。

  • パブリック IPv4 アドレスを自動割り当て → いいえ

これにより、ECSタスクが Private Subnet に配置されていることを確認できます。

ALB

1.AWSコンソール → EC2 を開く
2.左メニュー ロードバランサー をクリック
3.作成された ALB をクリック
4.「詳細」セクションで以下を確認します。

  • スキーム → internet-facing
  • VPC → 作成したVPC
  • ステータス → Active

次に、アベイラビリティーゾーンに表示されるサブネットのリンク(subnet-xxxx)をクリックし、サブネット詳細画面で以下を確認します。

  • パブリック IPv4 アドレスを自動割り当て → はい

※ サブネットは2つ表示されるため、それぞれ確認します。
これにより、ALBが Public Subnet に配置されていることを確認できます。

NAT Gateway

1.AWSコンソール → VPC を開く
2.左メニュー → NATゲートウェイ をクリック
3.以下を確認します。

  • NAT Gatewayが2つ作成されている
  • 各 NAT Gatewayが別々のPublic Subnet(AZ-A / AZ-B)に属している
  • ステータス → Available

次回

次回はRoute53を使って独自ドメインを設定し、ALB経由でアプリを公開します。

これにより、ALBのデフォルトドメインではなく、独自ドメインでアクセスできる環境が完成します。

第2回:Route53独自ドメイン設定編はこちら

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?