対象読者: AWSをこれから触る人。 AWS勉強シリーズの6本目で、今回はVPCです。全体の地図は索引記事にあります。
EC2を立てたのに、こういう症状で止まった人向けに書きます。
- 「サーバーは起動しているのに、外からアクセスできない」
- 「サブネットって何個作ればいいのか、そもそも何なのか分からない」
このどちらも、VPCの5つの部品(建物・部屋・玄関・案内板・警備員)のどれかが欠けているか、繋がっていないのが原因です。

VPCの部品をマンションに例えた図(筆者作成)。この記事の全部がこの1枚に入っています。
VPCとは何か
Amazon VPC(Virtual Private Cloud)は、AWSの中に自分専用のネットワークを区切って作るサービスです。EC2やRDSといったサーバー系のサービスは、必ずどこかのVPCの中に置きます。上の図でいうとVPCは「マンションの建物全体」で、その中に部屋(サブネット)を作り、玄関(インターネットゲートウェイ)を付け、案内板(ルートテーブル)で通り道を決め、各部屋のドアに警備員(セキュリティグループ)を立てます。VPC自体の料金は無料です(中に置くEC2やNATゲートウェイには料金がかかります)。
何に使うか
- 外に見せる部分と隠す部分を分ける: Webサーバーは外から見える部屋に、データベースは外から見えない部屋に置く。DBに直接インターネットから届かない構造にする
- 自分のIPアドレスの範囲を決める: 10.0.0.0/16 のように、社内ネットワークと被らない範囲を自分で選ぶ
- 通信の入口・出口を1か所に絞る: 玄関(インターネットゲートウェイ)を通らないと外に出られない、という構造で守る
- オンプレミスや別VPCと繋ぐ: VPN・Direct Connect・VPCピアリングの土台になる(この記事では扱いません)
重要用語
| 用語 | マンションで言うと | 意味 |
|---|---|---|
| VPC | 建物全体 | 自分専用のネットワークの範囲。IPの範囲(CIDR)を1つ持つ |
| サブネット | 部屋 | VPCの中をさらに区切った小さな範囲。1つのアベイラビリティゾーン(データセンター群)に属する |
| インターネットゲートウェイ(IGW) | 外への玄関 | VPCとインターネットを繋ぐ出入口。1つのVPCに1つ |
| ルートテーブル | 案内板 | 「この宛先はどこへ送るか」の表。サブネットごとにどの案内板を見るか決める |
| セキュリティグループ(SG) | 部屋のドアの警備員 | サーバー単位で「どのポートを誰に開けるか」を決める |
| パブリックサブネット | 外に面した部屋 | ルートテーブルにIGW向けの経路がある部屋 |
| プライベートサブネット | 内側の部屋 | IGW向けの経路がない部屋。外から直接届かない |
| CIDR | 部屋番号の範囲 |
10.0.0.0/16 のようなIP範囲の書き方。/16 は約65,000個、/24 は256個 |
仕組みの要点
初心者が一番つまずくのがここです。パブリックとプライベートの違いは、サブネットの種類ではなく、ルートテーブルの中身で決まります。 サブネットを作った時点では全部同じで、そのサブネットが見ている案内板に「0.0.0.0/0(全部の外)→IGW」という行があれば外に出られる部屋、無ければ出られない部屋になります。
実際に、ルートを何も設定していないサブネットが見ているルートテーブルの中身を取ると、こうなっています。
10.0.0.0/16 -> local
「VPCの中同士は通じる」の1行だけで、外への経路がありません。だからこの部屋のサーバーは、起動していてもインターネットから届きません。「サーバーは動いているのに外から繋がらない」の正体の一つがこれです。
もう一つ、警備員(セキュリティグループ)は通したいものだけを書く方式です。何も書かなければ全部止めます。443を開ける行を書いて初めてHTTPSが通ります。
使い方
「建物→部屋→玄関→案内板→警備員」の順に作ります。Python(boto3)での最小の形です。
import boto3
ec2 = boto3.client("ec2", region_name="ap-northeast-1")
# ① 建物: VPCを作る(IPの範囲を決める)
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
# ② 部屋: サブネットを作る(VPCの範囲の中から切り出す)
sub = ec2.create_subnet(VpcId=vpc, CidrBlock="10.0.1.0/24",
AvailabilityZone="ap-northeast-1a")["Subnet"]["SubnetId"]
# ③ 玄関: インターネットゲートウェイを作ってVPCに付ける
igw = ec2.create_internet_gateway()["InternetGateway"]["InternetGatewayId"]
ec2.attach_internet_gateway(InternetGatewayId=igw, VpcId=vpc)
# ④ 案内板: 「全部の外→玄関」の行を書いて、部屋に紐付ける
rt = ec2.create_route_table(VpcId=vpc)["RouteTable"]["RouteTableId"]
ec2.create_route(RouteTableId=rt, DestinationCidrBlock="0.0.0.0/0", GatewayId=igw)
ec2.associate_route_table(RouteTableId=rt, SubnetId=sub)
# ⑤ 警備員: 443番だけ通す
sg = ec2.create_security_group(GroupName="web", Description="web", VpcId=vpc)["GroupId"]
ec2.authorize_security_group_ingress(
GroupId=sg,
IpPermissions=[{"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443,
"IpRanges": [{"CidrIp": "0.0.0.0/0"}]}])
④まで終わった時点で、この部屋はパブリックサブネットになっています。④をやらなければ、同じ部屋がプライベートサブネットのままです。違いはコード1行(create_route)だけです。
実際に叩くと止まるところ
作り方を間違えたときにどんなエラーが返るかを、5パターン実際に叩きました。エラー文を読めれば、どの部品が悪いか分かります。
| やったこと | 返ってきたエラー | 意味 |
|---|---|---|
| VPCの範囲(10.0.0.0/16)の外にサブネット(10.1.0.0/24)を作る | InvalidSubnet.Range: The CIDR '10.1.0.0/24' is invalid. |
部屋は建物の中にしか作れない |
| 同じ範囲(10.0.1.0/24)のサブネットをもう1つ作る | InvalidSubnet.Conflict: conflicts with another subnet |
部屋番号の範囲は重ねられない |
| 1つのIGWを2つ目のVPCにも付ける | Resource.AlreadyAssociated |
玄関は1つのVPC専用。VPCごとに作る |
| サブネットが残っているVPCを消す | DependencyViolation: has dependencies and cannot be deleted. |
部屋を全部消してからでないと建物は壊せない |
| 存在しないSGにルール追加 | InvalidGroup.NotFound |
IDの打ち間違いや、別リージョンのSGを指している |
エラー名の頭(InvalidSubnet / DependencyViolation)がそのまま原因を言っている。まずエラー名で当たりを付けるのが早い。
サブネットは256個ぶんでも251個しか使えない
10.0.1.0/24 は計算上256個のIPを含みますが、実際に使えるのは251個でした。
10.0.1.0/24 の AvailableIpAddressCount = 251
AWSが各サブネットの先頭4つと末尾1つ、計5個を予約しているためです(ネットワークアドレス、VPCルーター、DNS、将来用、ブロードキャスト)。小さいサブネットを切るときは、この5個ぶん少なく見積もる。/28(16個)だと使えるのは11個しかない。
似た概念との使い分け
| 迷うところ | 答え |
|---|---|
| セキュリティグループとネットワークACL | SGはサーバー単位の警備員で、通したいものだけ書く(戻りの通信は自動で通る)。ネットワークACLはサブネット単位の門番で、許可と拒否を両方書く。最初はSGだけで足りる |
| パブリックとプライベート、どっちに置く | 外から直接アクセスされるもの(Webサーバー、ロードバランサ)はパブリック。それ以外(DB、内部処理)はプライベート |
| プライベートの中から外に出たいとき | NATゲートウェイをパブリック側に置いて、プライベート側の案内板を「0.0.0.0/0→NAT」にする。NATは有料 |
| VPCは何個作る | 最初は1つで十分。環境(本番/検証)を分けたくなったら分ける |
料金の考え方
VPC・サブネット・ルートテーブル・IGW・SGは無料です。料金がかかるのは、中に置くEC2などのリソースと、NATゲートウェイ(時間課金+データ量課金)、VPN接続、VPCピアリングのデータ転送などです。「VPCを作ったら課金される」ことはありません。初心者がVPC周りで請求を食らう典型はNATゲートウェイの消し忘れなので、そこだけ覚えておいてください。
よくある注意点
- デフォルトVPCがある。 AWSアカウントには最初からデフォルトVPCが1つ用意されていて、何も指定せずEC2を立てるとそこに入ります。学習用途ならそれで動きますが、中身を理解するには自分でVPCを1つ作ってみるのが早いです
- サブネットはアベイラビリティゾーンをまたげない。 冗長化するなら、別のAZにもう1つサブネットを作ります
- IGWを付けただけでは外に出られない。 案内板(ルートテーブル)に0.0.0.0/0→IGWの行を足して、それをサブネットに紐付けるまでがセットです
- 消す順番は作った逆。 SG→ルート→IGWのデタッチ→サブネット→VPC。順番を間違えるとDependencyViolationで止まります
まとめ
冒頭の2つの症状に戻ります。
- 「起動しているのに外からアクセスできない」→ ルートテーブルにIGW向けの行があるか、SGにそのポートの許可があるか。この2つで大半は決まります
- 「サブネットが何なのか分からない」→ VPCの中の部屋で、パブリックかプライベートかは案内板(ルートテーブル)の1行で決まる。部屋自体に種類はない
覚えるのは5部品(VPC・サブネット・IGW・ルートテーブル・SG)の関係だけです。上の図に全部入っています。
次回はLambda(サーバーレス)を予定しています。
参考
- Amazon VPC 公式ドキュメント
- 前回: 【図解】AWS EC2とは
- シリーズ索引: AWSとは何か