VPC + Subnet + Route Table — AWS のネットワーク基盤
概要
Amazon VPC (Virtual Private Cloud) は AWS 上に独立したプライベートネットワークを作る仕組みです。 EC2 / RDS / Lambda などのリソースをどこに配置するか、どこから通信を許可するかを制御する基盤になります。
サーバレス全盛でも VPC の理解は必須です。なぜなら、RDS や ElastiCache を使う時、Lambda を VPC 連携させる時、社内システムと VPN / Direct Connect で繋ぐ時など、 VPC 設計が後から変えにくい部分のため、初期設計で迷うとずっと尾を引きます。
主な構成要素
- VPC — CIDR ブロック (10.0.0.0/16 等) を持つ仮想ネットワーク。アカウント・リージョン単位で複数作成可能。
- Subnet — VPC を AZ 単位で分割した小ネットワーク。Public / Private で分けるのが定番。
- Route Table — 「この CIDR への通信はどこへ送るか」のルール集。Subnet ごとに紐付ける。
- IGW (Internet Gateway) — VPC をインターネットに繋ぐ出入口。Public Subnet に紐付く Route Table に
0.0.0.0/0 → igwを書く。 - NAT Gateway — Private Subnet から outbound する仕組み。EIP と組み合わせ。時間課金 + データ転送課金。
- VPC Endpoint — AWS サービス (S3 / DynamoDB 等) に VPC 内から直接接続する仕組み。NAT 不要化 / セキュリティ向上。
- Security Group (SG) — リソース単位のステートフルなネットワーク ACL。
- NACL (Network ACL) — Subnet 単位のステートレスな ACL。SG の補助。
- VPC Peering / Transit Gateway — 複数 VPC を相互接続する仕組み。
典型的な設計パターン (3 層)
- Public Subnet (10.0.10.0/24) — インターネット向け / ALB / NAT Gateway を置く
- Private (App) Subnet (10.0.20.0/24) — Lambda / EC2 / Fargate アプリを置く。NAT 経由で外向き
- Private (Data) Subnet (10.0.30.0/24) — RDS / ElastiCache を置く。インターネット直接アクセス不可
AZ ごとに同じ層を 2〜3 重複させ、計 6〜9 Subnet で構成するのが定番。
使うべきパターン
- RDS / ElastiCache を使う — VPC 内必須。Private Subnet に置く。
- EC2 / Fargate でアプリを動かす — Private Subnet + ALB Public Subnet の構成。
- オンプレ連携 — VPN Site-to-Site / Direct Connect で VPC 内に統合。
- セキュリティ / コンプライアンス要件 — VPC Flow Logs で全通信ログ取得。
使わない方が良いパターン (≒ デフォルト VPC で十分)
- 静的サイト + Lambda + DynamoDB — どれも VPC 不要。デフォルト VPC 放置で OK。
- 個人ポートフォリオ — VPC 設計に時間をかけても効果が薄い。S3 + CloudFront + サーバレスで完結させる。
- Lambda の VPC 連携を闇雲に有効化 — Cold Start 増加 + 料金増。RDS 等が本当に要る場合だけ。
Terraform 最小サンプル(Multi-AZ 3 層)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "main" }
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}
# Public Subnet x2
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${10 + count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0"; gateway_id = aws_internet_gateway.main.id }
}
resource "aws_route_table_association" "public" {
count = 2
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# Private Subnet x2 (NAT 経由 outbound)
resource "aws_eip" "nat" { domain = "vpc" }
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public[0].id
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${20 + count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
}
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0"; nat_gateway_id = aws_nat_gateway.main.id }
}
# VPC Endpoint (S3 / DynamoDB は無料の Gateway 型推奨)
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.region}.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_route_table.private.id]
}
用語集
- VPC
- Virtual Private Cloud。AWS 上の独立した仮想ネットワーク。
- CIDR
- Classless Inter-Domain Routing。IP アドレス範囲の表記法 (10.0.0.0/16 等)。
- Subnet
- VPC を AZ 単位で分割した小ネットワーク。
- Route Table
- 「この CIDR はどこへ送るか」のルール集。Subnet ごとに紐付け。
- IGW
- Internet Gateway。VPC をインターネットへ接続する出入口。
- NAT Gateway
- Private Subnet から outbound する仕組み。マネージドサービスなので運用不要。
- VPC Endpoint
- AWS サービスに VPC 内から直接接続する仕組み。Gateway 型 (S3/DDB 無料) と Interface 型 (有料) がある。
- Security Group
- リソース単位のステートフル ACL。Inbound/Outbound ルールを書く。
- NACL
- Subnet 単位のステートレス ACL。SG の補助、明示的 Deny が必要な時に使う。
- VPC Peering / Transit Gateway
- 複数 VPC を相互接続する仕組み。Transit Gateway は複数 VPC のハブ。
- VPC Flow Logs
- VPC 内の全通信ログを CloudWatch Logs / S3 に出力する機能。