「またIPアドレスが被ったのか……」
深夜のデータセンター、あるいは静まり返ったSlackのチャンネルで、何度この言葉を聞いてきたことでしょうか。複数のAWSアカウントが乱立し、それぞれのVPCが勝手気ままに 10.0.0.0/16 を切り出していく。事業が成長し、いざVPCピアリングやTransit Gatewayでネットワークを繋ごうとした瞬間、重複(オーバーラップ)という名の壁にぶち当たる。これは、成長するWebサービスが必ず通る「スケーラビリティの洗礼」とも言えます。
かつて我々SREは、巨大なExcelシートやスプレッドシートを「真実のソース(Source of Truth)」として、手作業でCIDRブロックを管理していました。しかし、そんな時代はもう終わりです。
今回は、大規模なマルチアカウント環境において、IPアドレス管理の苦行からエンジニアを解放する救世主、Amazon VPC IPAM (IP Address Manager) について深掘りします。パケットの流れる道を整える、その「設計図」の書き方を伝授しましょう。
—
1. なぜ「Excel管理」は破綻するのか?
RFC 1918で規定されたプライベートIPv4アドレス空間は広大に見えますが、有限です。
特にマイクロサービス化が進み、EKS(Elastic Kubernetes Service)などで大量のPodがIPを消費する現代のインフラでは、以下の問題が頻発します。
1. 重複の検知が遅れる: 接続設定(Peering)をするまで重複に気づけない。
2. 断片化: 空いている場所を適当に使った結果、連続した大きなブロックが取れなくなる。
3. 払い出しの属人化: 「インフラ担当のAさんに聞かないと、どのセグメントが空いているか分からない」。
Amazon VPC IPAMは、これらの課題を「ポリシーによる階層管理」と「自動割り当て」で解決します。
—
2. IPAMの階層構造:グローバルからサブネットまで
IPAMを理解する鍵は、「プール(Pool)」の階層構造にあります。
単一の大きな塊から、用途やリージョンに合わせて少しずつ切り分けていく、いわば「ピザを切り分ける」ようなイメージです。
階層設計のベストプラクティス
通常、以下のような3段構成で設計するのが定石です。
1. Top-level Pool (Global): 組織全体に割り当てられた巨大なCIDR(例: 10.0.0.0/8)。
2. Regional Pool: リージョンごとの割り当て(例: ap-northeast-1 に 10.1.0.0/12)。
3. Environment / Development Pool: 開発・本番環境や、特定のワークロード(EKS用など)への割り当て。
この階層構造を作ることで、「本番環境のVPCは必ずこの範囲から払い出す」という統制(ガバナンス)をプログラムで強制できるようになります。
—
3. 実践:Terraformで構築するIPAM階層
口を動かす前に手を動かしましょう。
AWSマネジメントコンソールでポチポチと設定するのは、再現性の観点からお勧めしません。ここでは、現場で即戦力となるTerraformを用いた定義例を紹介します。
IPAMスコープとトップレベルプールの作成
まずは、IPAM自体の器(Scope)を作り、組織全体の母体となるIP帯域を定義します。
# IPAM本体の作成
resource "aws_vpc_ipam" "main" {
description = "Organization wide IPAM"
operating_regions {
region_name = "ap-northeast-1"
}
operating_regions {
region_name = "us-west-2"
}
}
# トップレベルプールの作成(組織全体の親玉)
resource "aws_vpc_ipam_pool" "top_level" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.main.private_default_scope_id
description = "Top-level pool"
# 組織全体で使う広大なレンジ
publicly_advertisable = false
}
# トップレベルプールにCIDRをプロビジョニング
resource "aws_vpc_ipam_pool_cidr" "top_level_cidr" {
ipam_pool_id = aws_vpc_ipam_pool.top_level.id
cidr = "10.0.0.0/8"
}
リージョナルプールの作成
次に、東京リージョン(ap-northeast-1)専用のプールを、トップレベルプールから切り出します。ここで locale を指定するのがポイントです。
resource "aws_vpc_ipam_pool" "tokyo_pool" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.main.private_default_scope_id
source_ipam_pool_id = aws_vpc_ipam_pool.top_level.id # 親を指定
locale = "ap-northeast-1" # リージョンを固定
description = "Tokyo regional pool"
}
resource "aws_vpc_ipam_pool_cidr" "tokyo_cidr" {
ipam_pool_id = aws_vpc_ipam_pool.tokyo_pool.id
netmask_length = 16 # 10.x.0.0/16 形式で親から自動取得
}
—
4. 通信フローと自動割り当ての仕組み
VPCを作成する際、これまでは cidr_block = "10.1.0.0/16" とハードコードしていましたが、IPAMを使うと「IPAMプールから、特定のマスク長で勝手に持ってきてくれ」という指示が可能になります。
VPC作成時のシーケンス
1. リクエスト: ユーザーが aws_vpc を作成する際、ipv4_ipam_pool_id と ipv4_netmask_length を指定する。
2. チェック: IPAMが指定されたプール内に空きがあるかを確認。
3. アロケーション: 重複しないCIDR(例: 10.1.5.0/24)を自動的に計算し、VPCに「貸し出す」。
4. 記録: IPAMのダッシュボードに「どのVPCが、いつ、どのCIDRを消費したか」が記録される。
VPC作成のコード例
resource "aws_vpc" "app_vpc" {
# IPAMプールIDを指定
ipv4_ipam_pool_id = aws_vpc_ipam_pool.tokyo_pool.id
# 必要なサイズだけを指定(具体的なIP帯域はAWSにお任せ)
ipv4_netmask_length = 24
tags = {
Name = "Production-App-VPC"
}
}
このコードの美しさは、「エンジニアが次にどのIPが空いているか調べる必要がない」という点に集約されます。
—
5. 現場の知恵:可用性ゾーン(AZ)単位の設計とトラブルシューティング
実務では、VPC全体のCIDRだけでなく、その中の「サブネット」をどう分けるかも重要です。
AZ単位のCIDR設計
多くのシステムでは、AZ A, AZ C, AZ D にサブネットを分散させます。IPAMのポリシーで allocation_default_netmask_length などを設定しておけば、サブネット作成時もルールに基づいた切り出しが可能です。
トラブルシューティングのTips:
- Overlapの監視: IPAMには「非準拠(Non-compliant)」というステータスがあります。IPAM管理外で勝手に作られたVPCや、手動設定で重複したVPCを即座に見つけ出せます。
- 不足の検知: CloudWatch Metricsと連携し、プールの使用率が80%を超えたらアラートを飛ばすようにしましょう。CIDRが枯渇してからでは、ネットワークの再設計という地獄が待っています。
AWS CLIでの確認コマンド
現場で「今、どのIPがどれくらい使われているか」をサクッと確認するには、CLIが便利です。
# 特定のIPAMプールの利用状況を確認する
aws ec2 get-ipam-pool-allocations \
--ipam-pool-id ipam-pool-0123456789abcdef0 \
--region ap-northeast-1
—
結びに代えて:自動化の先にあるもの
Amazon VPC IPAMの導入は、単なる「IPアドレスの自動割り当て」ではありません。それは、「ネットワーク設計をコードとポリシーで統治する」という思想への転換です。
我々SREの仕事は、複雑なパズルを解くことではなく、パズルがそもそも発生しない仕組みを作ること。IPAMを使いこなし、Excel管理という名の技術負債を過去のものにしましょう。
もし、あなたの隣で後輩が「次のVPC、どのIPにしましょうか?」と聞いてきたら、静かにIPAMプールのIDを渡してあげてください。それが、プロフェッショナルとしての最短の回答なのです。
コメント