VPC設計の鍵は「Public/Privateの区画分け」「CIDRの余裕ある設計」「ルートテーブルのシンプル化」の3原則。Terraformでコード化し、将来の拡張に備えた「最高の街の地図」を設計しよう。
僕はVPCを、「自分たちがインフラを建設・運用する、独立した国(街)」として捉えています。
- VPC全体:国境線と全体の方針
- CIDR:国の人口規模(使えるIPアドレスの総数)
- サブネット:街の中の区画(商業区・住宅区・工業区)
この「街の地図作り」を適当にやると、後から「道が狭すぎて渋滞(通信不可)」「危険なエリアに重要施設を建ててしまった(セキュリティリスク)」という問題が発生します。この記事では「サブネット設計」に焦点を当て、初心者でも迷わない3つの原則を、実際のTerraform設計経験を交えて解説します。
🗺️ サブネット設計を「街の区画整理」で理解する
サブネットは、VPCのCIDRブロックを分割した個々のネットワークセグメント(区画)です。この区画整理をどう行うかが、安全で拡張性の高いインフラの鍵になります。
1 公開範囲で区画を分ける(Public / Private の原則)
街には「誰でも入れる商業エリア」と「外部からは遮断された住宅・機密エリア」が必要です。サブネットもこの公開範囲によって明確に二種類に分けます。
| サブネット | 街の比喩 | 役割 | 設置するAWSリソース例 |
|---|---|---|---|
| Public | 商業区 | 外部インターネットとの接続口 | ALB、踏み台サーバー、NAT GW |
| Private | 住宅区・機密エリア | 外部から直接アクセス不可 | DB(RDS)、APサーバー、Cache |
💡 鉄則
Private Subnet のサーバーは絶対に外部から直接アクセスできないようにします。大切なデータ(DBなど)は、Private という安全な区画に閉じ込めるのが基本です。
2 CIDR分割は「後で増える」を前提に設計する
VPCのCIDR(例:10.0.0.0/16)を決めたら、それをサブネットに分割します(例:10.0.1.0/24、10.0.2.0/24など)。サブネットのIPアドレス数はCIDRの最後の数字で決まり、/24なら256個(実質251個)が使用可能です。
📘 失敗しないコツ
用途ごとにIPアドレスの空きを意図的に残すこと。将来の監視サーバー追加やVPCピアリング用に、余裕あるCIDR設計が重要です。
⚠️ 筆者経験:土地不足の地獄
以前のプロジェクトで、サブネットをカツカツに分割した結果、後から「監視用サーバーの専用サブネット」「VPCピアリング接続用」が必要になり、IPアドレスの「土地不足」でVPCを作り直す地獄を見ました。設計段階での大局観が本当に大切です。
💬 Terraform での実装例
サブネットはAZ(アベイラビリティゾーン)ごとにPublicとPrivateをセットで作成し、将来の拡張用に/20や/22といった大きめのセグメントを予約しておくのが賢明です。以下は基本的なサブネット定義のコード例です。
# ====================================
# VPC 本体
# ====================================
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16" # 広めに取っておく
enable_dns_support = true
enable_dns_hostnames = true
tags = { Name = "main-vpc" }
}
# ====================================
# Public Subnet(商業区:外部公開用)
# ====================================
resource "aws_subnet" "public_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24" # /24 で余裕を持たせる
availability_zone = "ap-northeast-1a"
map_public_ip_on_launch = true # 外部IPを自動付与
tags = { Name = "public-subnet-1a" }
}
resource "aws_subnet" "public_c" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24" # 別AZにも配置(冗長化)
availability_zone = "ap-northeast-1c"
map_public_ip_on_launch = true
tags = { Name = "public-subnet-1c" }
}
# ====================================
# Private Subnet(住宅区:DB・APサーバー)
# ====================================
resource "aws_subnet" "private_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.10.0/24" # 番号帯を分けて管理しやすく
availability_zone = "ap-northeast-1a"
tags = { Name = "private-subnet-1a" }
}
resource "aws_subnet" "private_c" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.11.0/24"
availability_zone = "ap-northeast-1c"
tags = { Name = "private-subnet-1c" }
}
# ====================================
# Internet Gateway(街の外への大通り)
# ====================================
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = { Name = "main-igw" }
}
# ====================================
# Route Table: Public(外部への標識)
# ====================================
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 # IGWへ向ける
}
tags = { Name = "public-rtb" }
}
resource "aws_route_table_association" "public_a" {
subnet_id = aws_subnet.public_a.id
route_table_id = aws_route_table.public.id
}
resource "aws_route_table_association" "public_c" {
subnet_id = aws_subnet.public_c.id
route_table_id = aws_route_table.public.id
}
IaCでコード化しておけば、設計の意図がそのままドキュメントになり、再構築も容易です。Terraformモジュール設計の考え方も合わせて参照してください。
3 ルートテーブルは「標識」としてシンプルに保つ
サブネットの交通整理を行うのがルートテーブルです。設定のポイントは2つ:
- Public Subnet のルートテーブル: インターネットゲートウェイ(IGW)へのルートを設定(外部へのメインストリート)
- Private Subnet のルートテーブル: NATゲートウェイへのルートのみ設定(Privateからの安全な出口)
💡 街の地図の考え方
ルートテーブルはサブネットから出るトラフィックの「標識」です。この標識が複雑になると、どこへ通信が向かっているか分からなくなりデバッグが困難になります。「必要なルートだけ」を設定し、シンプルに保ちましょう。
⚠️ 注意点・失敗談:コストと CIDR の「はみ出し」
サブネット設計で初心者がつまずきやすい2大ポイントを紹介します。
1. NAT Gateway の常設コスト問題
Private Subnet がインターネットへ安全に出るためにNAT Gatewayが必要です。しかしNAT Gatewayは時間課金+データ処理量課金があり、AWS無料枠ではすぐに予算オーバーします。
💡 対策
検証環境では、使用しないときはNAT Gatewayを削除するか、より安価なNATインスタンス(EC2)の利用を検討しましょう。コスト管理の詳細は AWS無料枠の注意点まとめ も参考にしてください。
🔗 VPS で気軽に検証環境を作る
AWSの費用が気になる方には、VPS環境でLinuxやネットワーク設定を学ぶ方法もおすすめです。ConoHa VPS は時間課金で始められ、初期費用もゼロ。サブネット設計の実験場として活用できます。
2. CIDR 重複チェック(ピアリング時の鬼門)
複数のVPCを作る際やVPCピアリング(異なるVPC同士を接続)をする際、VPCやサブネットのCIDRが重複すると絶対に通信できません。
⚠️ 筆者経験:CIDR重複の罠
開発環境と本番環境で同じCIDR(10.0.0.0/16)を使ってしまった結果、ピアリング接続ができず途方に暮れたことがあります。設計の際は「次に作るであろうVPC」のIP帯域も確保しておく大局的な視点が大切です。
❓ よくある質問(FAQ)
Q1. VPCとサブネットの違いは何ですか?
VPCは「国全体」、サブネットは「その中の区画」です。VPCはAWSクラウド上に作る仮想ネットワーク空間全体を指し、サブネットはVPCのIPアドレス範囲(CIDR)をさらに分割した小さなネットワーク単位です。EC2やRDSなどのリソースは、VPCではなくサブネットに配置されます。
Q2. CIDRの /16 と /24 どちらを選べばいいですか?
VPC全体には広め(/16)、サブネットには /24 前後が定番です。
/16(65,536個)をVPCに割り当て、そこからサブネットを /24(256個)単位で切り出すのが一般的な設計パターンです。
| CIDR | IPアドレス数 | 主な用途 |
|---|---|---|
/16 |
65,536個 | VPC全体(広めに取る) |
/24 |
256個(実質251) | サブネット(1用途に十分) |
/28 |
16個(実質11) | 小規模検証・踏み台専用など |
Q3. Public Subnet と Private Subnet はどう使い分けますか?
外部から直接アクセスされる必要があるリソースのみ Public に配置し、それ以外は必ず Private に置くのが鉄則です。
- Public に置くもの:ALB(ロードバランサー)、NAT Gateway、踏み台サーバー
- Private に置くもの:RDS(DB)、アプリケーションサーバー(ECS/EC2)、Elasticache
「DBをPublicにしてとりあえず動かそう」は、セキュリティ事故の元になります。面倒でも最初から分けましょう。
Q4. NAT Gateway は必ず必要ですか?
Private Subnet 内のサーバーがインターネットへアウトバウンド通信(パッケージインストール、外部API呼び出しなど)を必要とする場合に必要です。完全にインターネットと切り離した閉じた環境であれば不要ですが、現実のシステムでは多くの場合必要になります。コストに注意し、検証環境では不使用時に削除することを検討しましょう。
Q5. Terraform で VPC 設計するメリットは何ですか?
コンソール操作との比較でTerraformを使う主なメリットは3点です。
- 再現性:同じ構成を開発・ステージング・本番で確実に再現できる
- ドキュメント化:コードそのものが設計書になる(IPアドレス管理表が不要)
- 変更管理:
terraform planで変更の影響を事前確認できる
詳しくは Terraformモジュール設計の記事を参照してください。
📚 まとめ:最高の「街の地図」を設計しよう
VPC設計は、インフラの安全と拡張性を決める「街の地図作り」そのものです。
✅ VPC設計の3つの原則
- Public / Privateで公開範囲に応じた区画整理を徹底する
- CIDRは「後で増える」を前提に、常に空きを確保する
- ルートテーブルはシンプルに保ち、交通整理の標識を明確にする
これらの原則をTerraformなどのIaCツールでコード化し、変更可能な「設計書」として管理することで、インフラ運用は格段に楽になります。設計の経験を積みながら、最高の街を作り上げましょう!

コメント