- 1 AWS Network本番運用Vol2 マルチアカウント網編|TGW × PrivateLink × Direct Connect × VPC Peering × Site-to-Site VPN 完全ガイド
- 1.1 1. なぜNetwork本番運用 Vol2 マルチアカウント網編か — VPC基礎+Hybrid編からの架橋 + 5本柱選定の現実解
- 1.2 2. Transit Gateway本番運用 — Route Table分離 × Attachment × Cross-Region Peering × Network Manager
- 1.3 3. PrivateLink本番運用 — Interface vs Gateway × Endpoint Service × クロスアカウント × Private DNS
- 1.4 4. Direct Connect本番運用 — Dedicated vs Hosted × VIF × LAG × DX Gateway × SiteLink × Resilient構成
- 1.5 5. VPC Peering vs Site-to-Site VPN — Peering特性 × VPN BGP vs Static × Accelerated VPN × 選定基準
- 1.6 6. 詰まりポイント7選 — マルチアカウント網本番運用の地雷とフィックス
- 1.7 7. アンチパターン→正解パターン変換演習5問
- 1.8 8. まとめ + Network Vol1↔Vol2双方向リンク + 落とし穴10選 + 全クロスリンク
- 1.9 1. なぜ Network Vol2 か — VPC 単体から マルチアカウント網 へ
- 1.10 2. Transit Gateway 本番運用 — Route Table 分離 × マルチアカウント × クロスリージョン
- 1.11 3. PrivateLink 本番運用 — Interface/Gateway/GWLB × クロスアカウント × Private DNS
- 1.12 4. Direct Connect 本番運用 — Dedicated/Hosted × LAG × Resilient構成 × BGP
- 1.13 5. VPC Peering vs Site-to-Site VPN — 選定基準 × BGP × Accelerated VPN
- 1.14 6. 詰まりポイント7選 — マルチアカウント網本番運用の地雷とフィックス
- 1.14.1 6-1. TGW Route Table 単一化 — 環境間通信全開放によるセグメント設計崩壊
- 1.14.2 6-2. PrivateLink 許可リスト破綻 — Allowed Principals 未設定によるサービス停止
- 1.14.3 6-3. DX Single Location 回線断 — Resilient構成未整備によるオンプレフルダウン
- 1.14.4 6-4. VPC Peering CIDR重複 — グローバル一意性未確保による Peering 不能
- 1.14.5 6-5. Site-to-Site VPN Tunnel Flap — BGP 未設定によるフェールオーバー遅延
- 1.14.6 6-6. TGW Quota 超過 — Attachment 数上限到達による新規 VPC 接続不能
- 1.14.7 6-7. Network Manager 未活用 — Route 分析・変更影響把握不能
- 1.15 7. アンチパターン→正解パターン変換演習
- 1.15.1 演習1: TGW Default Route Table 全利用 → 環境別 Route Table 分離
- 1.15.2 演習2: PrivateLink Acceptance Required 無効 → Allowed Principals + Organizations 連携
- 1.15.3 演習3: DX Single Location 1 回線 → Multi-Location 2 回線 + VPN Failover
- 1.15.4 演習4: VPC Peering Mesh 構成 → TGW Hub-and-Spoke 移行
- 1.15.5 演習5: Site-to-Site VPN Static Route → BGP 動的経路 + BFD 設定
- 1.15.6 演習6: CIDR 重複を後付け対応 → IPAM 導入で CIDR 一元管理
- 1.15.7 演習7: クロスアカウント PrivateLink 手動管理 → Organizations OU 連携 + RAM 自動化
- 1.16 8. まとめ — マルチアカウント網本番運用への道と次のステップ
AWS Network本番運用Vol2 マルチアカウント網編|TGW × PrivateLink × Direct Connect × VPC Peering × Site-to-Site VPN 完全ガイド

本記事は VPC基礎 (Transit Gateway / VPC Lattice / PrivateLink 統合実装入門) と Hybrid Connectivity 専門編 (Direct Connect × VPN × TGW 運用) を完遂した中堅エンジニア向けの本番マルチアカウント網実装ガイドです。Transit Gateway × PrivateLink × Direct Connect × VPC Peering × Site-to-Site VPN の 5本柱統合で、20-100アカウント規模のマルチアカウント網を本番品質で運用する設計力を確立します。
既存Network記事との住み分け
- VPC基礎 (Vol1相当 / TGW × VPC Lattice × PrivateLink 統合実装入門): 単体VPC/小規模TGW設計入門
- Hybrid Connectivity 専門編 (DX × VPN × TGW): オンプレ ↔ AWS 接続専門・ハイブリッド焦点
- 本Vol2 マルチアカウント網編 = 5本柱統合本番運用: Multi-Account網設計 × 大規模TGW運用 × クロスアカウントPrivateLink × 本番Resilient DX × Peering vs VPN選定
選定基準: 20アカウント以上 / Multi-Region本番網 / オンプレ常時接続必須 / DX物理冗長化必須 → 本Vol2推奨。
1. なぜNetwork本番運用 Vol2 マルチアカウント網編か — VPC基礎+Hybrid編からの架橋 + 5本柱選定の現実解
TODO: 本セクションでは以下を解説する。
– VPC基礎+Hybrid専門編完遂後にチームが直面する5つの壁 (マルチアカウント網設計破綻 / TGW Route Table暴走 / クロスアカウントPrivateLink複雑性 / DX物理冗長化要件 / Peering vs VPN選定の混乱)
– 5本柱選定の現実解 (TGW=ハブ / PrivateLink=サービス公開 / DX=オンプレ高帯域 / Peering=低レイテンシ少数間 / Site-to-Site VPN=DXバックアップ)
– VPC基礎との連続性 (基礎=単体VPC設計入門 / 本Vol2=Multi-Account網統合運用)
– Hybrid専門編との補完性 (Hybrid=DX/VPN詳細運用 / 本Vol2=5本柱選定+本番マルチアカウント網設計)
– 本Vol2で得られる5成果 (TGW Multi-Account網設計 / クロスアカウントPrivateLink / DX Resilient構成 / VPC Peering選定基準 / Site-to-Site VPN BGP本番運用)
– Network本番運用5原則 (Hub-and-Spokeトポロジ標準化 / Route Table分離による blast radius局所化 / クロスアカウント明示的許可 / 物理冗長化必須 / 観測性Network Manager統合)
- 痛点1: TGW Route Table単一化で全アカウント全VPC相互接続→ blast radius全社拡散
- 痛点2: クロスアカウントPrivateLink Endpoint Service許可リスト管理破綻 (100アカウント手動許可)
- 痛点3: Direct Connect単一回線 (Resilient未構成) で物理障害時のオンプレ全停止
- 痛点4: VPC Peering 100ペアでMesh構造化 → Route Table管理不能
- 痛点5: Site-to-Site VPN Static Route運用で経路変更時に手作業数十件
VPC基礎 — TGW×VPC Lattice×PrivateLink 統合実装入門
2. Transit Gateway本番運用 — Route Table分離 × Attachment × Cross-Region Peering × Network Manager

TODO: 本セクションでは以下を解説する。
– Transit Gateway 4要素 (TGW本体 / Attachment / Route Table / Propagation) の役割
– Route Table分離設計 (Prod/Stg/Dev/Shared/Egress 5パターン分離 / blast radius局所化)
– Attachment種別 (VPC / DX Gateway / VPN / TGW Peering / Connect: SD-WAN) の使い分け
– Cross-Region TGW Peering (Multi-Region Hub-and-Spoke 構築 / 経路広告制御)
– Network Manager 統合監視 (Global Network / Topology可視化 / Event監視)
– RAM (Resource Access Manager) でクロスアカウントTGW共有設計
– 本番Quota管理 (Attachment上限 5,000 / Route上限 10,000 / Hard Limit緩和申請)
– mermaid01: TGW Route Table分離フロー (Prod VPC → Prod RT → Egress VPC のみ許可)
- 原則1: Route Tableを最低5本 (Prod/Stg/Dev/Shared/Egress) 分離し blast radiusを局所化
- 原則2: クロスアカウントTGW共有はRAMで明示的・最小権限設計
- 原則3: Multi-Region網は TGW Peering + Cross-Region Route 制御 で広告経路を厳格管理
- 原則4: Network Manager Global Network で TGW + DX + VPN を統合可視化
- 原則5: Quota (Attachment 5000 / Route 10000) を Hard Limit到達前に緩和申請
- Prod RT: Production VPC群のみ相互接続 / Egress VPCへの経路のみ
- Stg RT: Staging VPC群のみ / Prod RTとは隔離
- Dev RT: Development VPC群のみ / 自由度高
- Shared RT: 共通サービス (DNS / ログ集約 / 監査基盤) を全環境から接続
- Egress RT: NAT/Internet Gateway経由のアウトバウンド集約
3. PrivateLink本番運用 — Interface vs Gateway × Endpoint Service × クロスアカウント × Private DNS
TODO: 本セクションでは以下を解説する。
– VPC Endpoint種別 (Interface Endpoint / Gateway Endpoint / GatewayLoad Balancer Endpoint) の役割
– Interface Endpoint本番運用 (1ENI/AZ あたりコスト / VPC内DNS解決 / SG設計)
– Gateway Endpoint本番運用 (S3/DynamoDB 専用 / Route Table追記方式 / 無料)
– Endpoint Service (PrivateLink Service Provider) でクロスアカウントサービス公開設計
– 許可リスト管理 (Acceptance Required / Allowed Principals / 大規模アカウント運用パターン)
– Private DNS統合 (Endpoint Service Private DNS / Route 53 Resolver連携 / DNS-based Service Discovery)
– AWS Service Endpoint運用 (主要サービスでの設定パターン / S3 Interface vs Gateway選定)
– 本番Quota (Endpoint数 / Interface接続数 / 帯域 10Gbps/AZ)
- 原則1: S3/DynamoDBはGateway Endpoint (無料) を第一選択 / 他はInterface Endpoint
- 原則2: Endpoint Service許可リストは Organizations OU単位で管理 (手動許可禁止)
- 原則3: Private DNS統合で内部DNS解決 (FQDN変更なしでサービス利用)
- 原則4: クロスリージョンサービス公開は VPC Lattice or DX Gateway 経由で構成
- 原則5: Interface Endpoint帯域 (10Gbps/AZ) 監視必須・上限到達時はScale Out
TODO: 詳細解説 — Acceptance Required運用で個別アカウント手動許可を続けると、新規アカウント追加毎に手作業発生・許可漏れ事故温床。Organizations OU連携 + Tag-based Access Control (Allowed Principals に OU ARN指定) で自動化が正解。
4. Direct Connect本番運用 — Dedicated vs Hosted × VIF × LAG × DX Gateway × SiteLink × Resilient構成

TODO: 本セクションでは以下を解説する。
– Direct Connect 種別 (Dedicated 1G/10G/100G / Hosted 50M〜10G) の選定マトリクス
– VIF種別 (Private VIF: VPC接続 / Public VIF: AWS Public IP / Transit VIF: TGW接続) の使い分け
– LAG (Link Aggregation Group) で複数回線束ねて冗長化+帯域拡張
– DX Gateway運用 (Multi-Region VPC接続 / Multi-Account共有 / Allowed Prefixes制御)
– SiteLink (DX間トラフィック AWS Backbone転送 / オンプレ拠点間バックホール削減)
– Resilient構成パターン (Single Location 1回線=NG / Single Location 2回線 / Multi-Location 2回線=本番推奨)
– BGP本番運用 (LOCAL_PREF / AS_PATH Prepending / MED / Community Tagging で経路制御)
– 本番障害対応 (CloudWatch BGP Status監視 / VPN自動Failover / SNS通知)
- 原則1: 本番はMulti-Location 2回線 Resilient構成必須 (Single Location は冗長化不十分)
- 原則2: DX Gateway経由でMulti-Region/Multi-Account共有 (Allowed Prefixesで経路統制)
- 原則3: SiteLinkで拠点間バックホール削減 (専用線コスト最適化)
- 原則4: BGP Community Tagging で本番/開発トラフィック分離
- 原則5: DX障害時のVPN自動Failoverを必ず設計 (Active-Standby構成)
- Single Location 1回線: 検証/開発のみ / SLAなし / 本番禁止
- Single Location 2回線 (Resiliency): ロケーション内冗長 / 99.9% SLA / 小規模本番
- Multi-Location 2回線 (High Resiliency): 物理ロケーション冗長 / 99.99% SLA / 本番推奨
- Multi-Location 4回線 (Maximum Resiliency): 完全冗長 / 99.999% SLA / 金融/Mission Critical
5. VPC Peering vs Site-to-Site VPN — Peering特性 × VPN BGP vs Static × Accelerated VPN × 選定基準

TODO: 本セクションでは以下を解説する。
– VPC Peering の本質 (1:1直接接続 / Transitive Routing不可 / 低レイテンシ / 同/Cross-Account/Cross-Region対応)
– Peering制約 (Mesh構造で N(N-1)/2 ペア必要 / Route Table肥大 / SG参照Cross-Region不可)
– Site-to-Site VPN種別 (Customer Gateway / Transit Gateway VPN Attachment / Cloud WAN VPN)
– BGP vs Static Route (BGP=動的経路 / Static=10経路上限 / 障害時自動Failover条件)
– Accelerated Site-to-Site VPN (Global Acceleratorで AWS Backboneに最短入線 / Latency改善)
– VPN Performance最適化 (ECMP / Multi-Tunnel / Active-Active構成)
– Customer Gateway 高可用化 (オンプレ側2台冗長 / 異なるISP回線推奨)
– 本番監視 (CloudWatch VPN Tunnel状態 / IPSec Phase1/2 / BGP Session監視)
– mermaid02: Peering vs VPN vs TGW 選定判断フロー (アカウント数・接続要件で分岐)
- 原則1: VPC Peeringは「特定2VPC間の低レイテンシ通信」のみ採用 (Mesh構造化禁止)
- 原則2: 3VPC以上の相互接続はTransit Gateway一択 (Peering Meshはアンチパターン)
- 原則3: Site-to-Site VPNはBGP動的経路必須 (Static Routeは10経路上限+運用負荷大)
- 原則4: 重要拠点はAccelerated VPN+Customer Gateway冗長化 (Active-Active)
- 原則5: VPN Tunnel状態+BGP Session+IPSec Phase状態を統合監視 (PagerDuty連携)
TODO: 詳細解説 — 10VPC Mesh = 45 Peering Connection が必要。Route Table追加・SG参照管理が爆発的に複雑化。Transit Gateway Hub-and-Spokeで 10 Attachment + 1 Route Table に縮約が正解。VPC数増加に対し O(N) で線形拡張。
6. 詰まりポイント7選 — マルチアカウント網本番運用の地雷とフィックス
TODO: 本セクションでは以下を解説する。
詰まりポイント7選
- TGW Route Table単一化で blast radius全社拡散: Prod/Stg/Dev/Shared/Egress 5本分離+Propagation制御で局所化。
- クロスアカウントPrivateLink許可リスト破綻: Acceptance Required + Allowed Principals (OU ARN) でOrganizations連携自動化。
- DX Single Location冗長化不足で物理障害時オンプレ全停止: Multi-Location 2回線 Resilient構成必須+VPN自動Failover設計。
- VPC Peering Mesh構造で Route Table肥大: 3VPC以上はTransit Gateway一択+Route Table分離。
- Site-to-Site VPN Static Route 10経路上限到達: BGP動的経路移行 (BGP Community Tagging で本番/開発分離)。
- TGW Quota (Attachment 5000) 到達でnew VPC接続不可: 早期 Quota監視+Hard Limit緩和申請ワークフロー設計。
- Network Manager未活用でマルチアカウント網可視化困難: Global Network設定 + Event Stream → 統合Topology監視。
- TGW Route伝播失敗 → Propagation設定確認 + Static Route追記 → CloudWatch Metric監視
- PrivateLink許可拒否 → Acceptance Required解除 or Allowed Principals OU追加
- DX BGP Session Down → CloudWatch Alarm → VPN自動Failover発火 → ISP連絡フロー
- VPN Tunnel片肺 → IPSec Phase1/2再ネゴ → Customer Gateway切替試験
7. アンチパターン→正解パターン変換演習5問
TODO: 本セクションでは以下を解説する。
- 演習1: TGW Route Table単一化 (全VPC全相互接続) → 5本分離 (Prod/Stg/Dev/Shared/Egress) + Propagation制御
- 演習2: VPC Peering Mesh構造 (10VPC=45ペア) → Transit Gateway Hub-and-Spoke (10 Attachment)
- 演習3: DX Single Location 1回線 → Multi-Location 2回線 Resilient構成+VPN自動Failover
- 演習4: PrivateLink Acceptance Required手動許可 → Allowed Principals (OU ARN) Organizations自動連携
- 演習5: Site-to-Site VPN Static Route運用 → BGP動的経路+Community Tagging本番/開発分離
各演習で「現状の問題点」「正解への移行手順 (Terraform例)」「Trade-off」を解説する。
8. まとめ + Network Vol1↔Vol2双方向リンク + 落とし穴10選 + 全クロスリンク
TODO: 本セクションでは以下を解説する。
– Vol2で習得した5本柱統合本番運用パターンの総括 (TGW + PrivateLink + DX + Peering + VPN)
– 落とし穴10選 (VPC基礎+Hybrid編+本番マルチアカウント網横断のチェックリスト)
– Network Vol1↔Vol2 連続性 (Vol1=単体VPC基礎 / 本Vol2=Multi-Account網本番運用)
– Hybrid専門編との補完性 (Hybrid=DX/VPN詳細 / 本Vol2=5本柱選定+本番設計)
– Vol3予告: Service Mesh (VPC Lattice深掘り) / Cloud WAN / Multi-Region Active-Active網
– Network本番運用シリーズ完成度宣言: VPC基礎 + Hybrid専門編 + 本Vol2 で AWS Network運用三本柱を網羅
- Transit Gateway Route Table分離+Cross-Region Peering+Network Managerでマルチアカウント網を本番設計
- PrivateLink Interface/Gateway/Endpoint ServiceでクロスアカウントAWS Native接続
- Direct Connect Multi-Location Resilient+DX Gateway+SiteLinkで物理冗長+コスト最適化
- VPC Peering vs Site-to-Site VPN 選定基準で接続パターンを的確判断
- BGP本番運用+Community Tagging+Accelerated VPNで動的経路+性能最適化
- IAM: Vol1 IAM ポリシー設計
- EKS: Vol1 クラスタ設計 IRSA×ALB Ingress
- 復旧: Incident Response Runbook
- AI Bedrock: Vol1 Bedrock Agents
- セキュリティ: Vol1 セキュリティ運用
- コスト: Vol1 Cost Optimization
- マルチアカウント: Vol1 Multi-Account
- Observability: Vol1 Application Signals
- Network: VPC基礎 TGW×Lattice×PrivateLink入門 / Hybrid専門編 DX×VPN×TGW / Vol2 マルチアカウント網編 (本記事)
- DevOps: Vol1 CodePipeline
- Database: Vol1 RDS×Aurora×DynamoDB / Vol2 DMS×Aurora Global / Vol3 ElastiCache×DAX×MemoryDB
- Serverless: Vol1 Lambda×API GW×SF / Vol2 EventBridge×SQS
- Container: Vol1 ECS×Fargate×ECR / Vol2 GitOps編 ArgoCD×Kustomize×Argo Rollouts
- Storage: Vol1 S3×EFS×FSx×Storage Gateway
- Edge/CDN: Vol1 CloudFront×Lambda@Edge×Route53
- Analytics: Vol1 Glue×Athena×Redshift
- ML/AI: Vol2 Bedrock Embedding×RAG×Agents
VPC基礎 — TGW×VPC Lattice×PrivateLink 統合実装入門
1. なぜ Network Vol2 か — VPC 単体から マルチアカウント網 へ
1-1 VPC基礎 (Vol1) からの架橋: 単体VPCで止まる限界
VPC基礎編では Transit Gateway の基本構成・VPC Lattice によるサービスメッシュ・PrivateLink の統合実装入門を学んだ。単一アカウント・数個の VPC をつなぐ設計においては、この知識で十分な本番品質を達成できる。しかし組織が成長し、アカウント数が 10 を超え、20 を超え、マルチリージョン展開が始まった瞬間に、従来の設計思想は根本から問い直される。
単体 VPC 設計で止まることの限界は 3 層に分類できる。第一層は トポロジーの限界だ。アカウント数が増えると VPC Peering のフルメッシュは指数的に複雑化し、100 ペアを超えた時点でルートテーブルの手動管理は人間の能力を超える。第二層は セキュリティ境界の限界だ。TGW を単一ルートテーブルで運用すると、すべての VPC が相互到達可能になり、1 つのアカウントの侵害が全社に波及するブラスト半径が生まれる。第三層は 運用スケールの限界だ。クロスアカウントでのサービス公開・Private DNS の解決・許可リスト管理は、手動運用では数十アカウントで破綻する。
本 Vol2 では、VPC基礎で習得した TGW・PrivateLink・Direct Connect の基礎知識を前提として、20〜100 アカウント規模のマルチアカウント網を本番品質で設計・運用する 5 本柱を体系的に習得する。
- VPC基礎 (Vol1相当): 単体VPC設計 / 小規模TGW基本設定 / PrivateLink入門 / VPC Lattice統合 — アカウント数 1〜5 の小規模構成に最適
- Hybrid Connectivity 専門編: Direct Connect 詳細運用 / Site-to-Site VPN BGP設定 / オンプレ↔AWS接続専門 — ハイブリッド接続が主テーマ
- 本Vol2 マルチアカウント網編: TGW Route Table 5本分離 / RAM クロスアカウント共有 / クロスリージョン Peering / PrivateLink クロスアカウント / DX Resilient構成 / VPC Peering vs VPN選定 — アカウント数 20〜100 の本番大規模構成に対応
本Vol2を選ぶ基準: アカウント数 ≥ 20 / マルチリージョン本番網 / オンプレ常時接続 / DX物理冗長化必須 のいずれかに該当する場合。
VPC基礎 — TGW × VPC Lattice × PrivateLink 統合実装入門
VPC基礎で学んだ TGW の基本的な Attachment 作成・ルートテーブルへの登録・BGP 自動経路広告の仕組みは、本 Vol2 でも基礎として活用する。Vol1 の知識を持つ読者は、2章から直接 TGW Route Table 分離設計に入ることができる。
1-2 マルチアカウント網の痛点5選 — 実際に詰まる問題
マルチアカウント網を本番運用するエンジニアが必ず直面する 5 つの痛点を具体的に解説する。これらは教科書的な問題ではなく、実際の運用現場で発生する詰まりポイントだ。
痛点 1: TGW Route Table 単一化によるセグメント越境
TGW を最初に構築する際、ルートテーブルを 1 本で運用するケースは多い。すべての VPC Attachment を同一 Route Table に登録し、全 VPC 相互通信を許可する「フルメッシュ単一 RT」構成だ。この設計は小規模では機能するが、アカウント数が増えた段階で致命的な問題を引き起こす。Production VPC が Staging VPC と直接通信可能になり、Development アカウントのエンジニアが誤って Production データベースに接続できてしまう。さらに、1 つのアカウントがセキュリティインシデントに遭遇した場合、同一 Route Table に参加する全 VPC にブラスト半径が及ぶ。解決策は Route Table を環境ごとに 5 本 (Prod/Stg/Dev/Shared/Egress) に分離し、各 RT の Propagation と Static Route を厳格に制御することだ。
痛点 2: クロスアカウント PrivateLink 許可制御の崩壊
PrivateLink の Endpoint Service は、サービス利用者のアカウントを Whitelist で許可する仕組みを持つ。アカウント数が少ない間は手動管理で回るが、50 アカウントを超えると許可リストの追加・削除・棚卸しが追いつかなくなる。新規アカウントへのサービス公開忘れ・退役アカウントの許可残存・誰がどのサービスに接続許可されているかの全体把握不能、という 3 種の混乱が同時発生する。解決策は AWS RAM (Resource Access Manager) と Organizations 統合を組み合わせ、OU 単位の一括許可と Terraform による許可リスト IaC 管理を導入することだ。
痛点 3: Direct Connect Single Location の回線断リスク
Direct Connect を 1 拠点・1 物理ポートで運用している構成は、物理ケーブル切断・ロケーション障害・BGP セッション断で即座にオンプレ ↔ AWS 接続が全断する。「先週まで問題なかった」という運用実績は物理障害に対して何の防御にもならない。Resilient 構成の基本は 2 拠点・2 物理ポートの冗長化 (DX Gateway + LAG) だが、さらに Site-to-Site VPN をバックアップとして併用することで、DX 全断時のフェイルオーバー経路を確保する。
痛点 4: VPC Peering CIDR 重複による設計制約
VPC Peering は 1 対 1 の直接接続であり、推移的なルーティングをサポートしない。アカウント数が増えると「Peering 相手と CIDR が重複してしまった」という問題が頻発する。10.0.0.0/16 を使い回してしまった複数の VPC は、相互に Peering できない。さらに Peering の数が 100 を超えると Route Table エントリの管理が不能になり、通信の疎通確認コストが指数的に増加する。TGW への移行・CIDR 再設計・プライベート IP アドレス体系の組織標準化が根本解決となる。
痛点 5: Site-to-Site VPN の Static Route から BGP 移行タイミングの見誤り
初期構築で Static Route を選択した Site-to-Site VPN は、経路が増えるたびに手動でルートを追加する必要がある。オンプレ側のサブネットが増えるたびに AWS コンソールで Static Route を追加し、Customer Gateway 側でも設定変更が発生する。BGP への移行タイミングを見誤ると、50 本以上の Static Route を手動管理し続ける運用地獄に入る。BGP (Border Gateway Protocol) への移行は経路数が 10 を超えた段階で検討を開始し、Customer Gateway デバイスが BGP に対応していることを事前確認した上で移行設計を立てることが重要だ。
1-3 5本柱選定の現実解 — TGW / PrivateLink / DX / Peering / VPN
マルチアカウント網の構成要素として 5 本柱を選定した理由は、それぞれが明確に異なる役割を担い、組み合わせることで疎結合・高可用・低コストのネットワーク基盤を実現するからだ。5 本柱はトレードオフの関係にあり、すべてを同じ規模で導入する必要はない。組織の規模・要件・予算に応じて組み合わせを選択する。
- Transit Gateway (TGW): 役割=Hub-and-Spoke のハブ / 適用場面=VPC 間通信 3 つ以上 / 代替不可条件=マルチアカウント網の中央ルーター / 月額コスト=Attachment 数 × $0.05 + データ転送 $0.02/GB
- PrivateLink: 役割=マネージドサービスの内部公開 / 適用場面=クロスアカウントでのサービス API 公開 / 代替不可条件=インターネット非経由・Private IP 維持 / 月額コスト=Endpoint $0.01/h + データ転送 $0.01/GB
- Direct Connect (DX): 役割=オンプレ ↔ AWS 専用線 / 適用場面=大帯域・低レイテンシ・一定品質要件 / 代替不可条件=100Mbps 以上常時転送・コンプライアンス要件 / 月額コスト=ポート時間料金 + データ転送
- VPC Peering: 役割=少数 VPC 間の直接低レイテンシ通信 / 適用場面=2〜5 VPC 間・同一リージョン / 代替不可条件=TGW のホップレイテンシが許容できない場合 / 月額コスト=データ転送のみ (接続料金なし)
- Site-to-Site VPN: 役割=オンプレ ↔ AWS 暗号化通信 / 適用場面=DX バックアップ・小規模拠点接続 / 代替不可条件=DX が引けない拠点・DX 障害時フェイルオーバー / 月額コスト=VPN 接続 $0.05/h + データ転送 $0.09/GB
選定フロー: まず TGW で Hub 確立 → クロスアカウントサービス公開が必要なら PrivateLink → オンプレ接続が必要なら DX (大帯域) or Site-to-Site VPN (バックアップ/小規模) → 特定 VPC 間の超低レイテンシが必要なら VPC Peering を追加。
flowchart TD
subgraph ProdAccount["Prod Account"]
ProdVPC1["Prod VPC-A\n10.1.0.0/16"]
ProdVPC2["Prod VPC-B\n10.2.0.0/16"]
end
subgraph StagAccount["Stg Account"]
StagVPC["Stg VPC\n10.10.0.0/16"]
end
subgraph SharedAccount["Shared Services Account"]
SharedVPC["Shared VPC\n10.100.0.0/16"]
end
subgraph EgressAccount["Egress Account"]
EgressVPC["Egress VPC\n10.200.0.0/16\nNAT Gateway"]
end
ProdVPC1 -->|Attachment| ProdRT["Prod Route Table\n(Prod VPC群のみ Propagation)\n→ Egress RT へのみ Static Route"]
ProdVPC2 -->|Attachment| ProdRT
StagVPC -->|Attachment| StagRT["Stg Route Table\n(Stg VPC群のみ Propagation)\n→ Egress RT へのみ Static Route"]
SharedVPC -->|Attachment| SharedRT["Shared Route Table\n(全環境 VPC からの受信)"]
EgressVPC -->|Attachment| EgressRT["Egress Route Table\n(0.0.0.0/0 のみ)\nNAT → Internet"]
ProdRT -->|"Prod → Shared のみ許可"| SharedRT
StagRT -->|"Stg → Shared のみ許可"| SharedRT
ProdRT -. "Prod → Stg 不可\n(RT分離で遮断)" .-> StagRT
style ProdRT fill:#4a90d9,color:#fff
style StagRT fill:#7b68ee,color:#fff
style SharedRT fill:#5cb85c,color:#fff
style EgressRT fill:#f0ad4e,color:#000
mermaid01: TGW Route Table 分離フロー — Prod VPC から Stg VPC への直接通信を Route Table 分離で遮断し、Shared Services と Egress のみ許可するセグメント設計
2. Transit Gateway 本番運用 — Route Table 分離 × マルチアカウント × クロスリージョン
Transit Gateway (TGW) はマルチアカウント網の中央ルーターとして機能する。Hub-and-Spoke トポロジの Hub を担い、すべての VPC・Direct Connect Gateway・Site-to-Site VPN が Spoke として Attachment を通じて接続する。単体 VPC 設計では 1 本の Route Table で事足りていたが、マルチアカウント本番運用では Route Table の分離設計が最も重要な設計上の意思決定になる。
TGW を構成する 4 要素を理解することが、本番設計の出発点となる。
| 要素 | 役割 | 本番での考慮点 |
|---|---|---|
| TGW 本体 | Hub ルーター実体。Amazon Side ASN を設定し BGP セッションを確立 | auto_accept_shared_attachments = disable で手動承認を強制。デフォルト RT 無効化が必須 |
| Attachment | VPC・DX Gateway・VPN・TGW Peering などの接続単位 | Attachment ごとに関連付ける Route Table を明示指定。デフォルト RT への自動登録を禁止 |
| Route Table | 経路解決ルールの集合。Attachment が「どのルートを使うか」を決定 | 環境ごとに 5 本以上に分離。Propagation と Static Route を組み合わせて経路制御 |
| Propagation | Attachment が持つ CIDR を Route Table に自動広告する仕組み | どの Attachment のルートをどの RT に広告するかを明示制御。誤 Propagation が経路漏洩の原因になる |
Route Table 分離設計の核心は「Propagation の制御」にある。すべての Attachment を同一 RT に Propagation すれば全 VPC が相互到達可能になる。環境ごとに RT を分け、それぞれに必要な Attachment の Propagation のみを登録することで、ブラスト半径を環境内に閉じ込める。
2-1 TGW Route Table 分離設計 (Prod/Stg/Dev/Shared/Egress 5本)
Route Table を環境ごとに 5 本分離することで、ブラスト半径を環境内に局所化し、クロス環境通信を明示的に制御できる。Prod RT には Prod VPC の Attachment のみを Propagation し、Stg や Dev の経路は一切広告しない。Egress への経路 (0.0.0.0/0) のみ Static Route として追加し、インターネットアクセスは Egress VPC の NAT Gateway に集約する。
# Transit Gateway 本体
resource "aws_ec2_transit_gateway" "main" {
description= "Multi-Account Hub TGW"
amazon_side_asn = 64512
auto_accept_shared_attachments = "disable"
default_route_table_association = "disable"
default_route_table_propagation = "disable"
dns_support= "enable"
vpn_ecmp_support = "enable"
tags = {
Name = "tgw-main"
Env = "shared"
}
}
# Prod VPC Attachment
resource "aws_ec2_transit_gateway_vpc_attachment" "prod_a" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
vpc_id = var.prod_vpc_a_id
subnet_ids= var.prod_vpc_a_tgw_subnet_ids
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
tags = { Name = "attach-prod-vpc-a", Env = "prod" }
}
# Prod Route Table (Prod VPC群のみ)
resource "aws_ec2_transit_gateway_route_table" "prod" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags= { Name = "rt-prod" }
}
resource "aws_ec2_transit_gateway_route_table_association" "prod_a" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.prod_a.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
resource "aws_ec2_transit_gateway_route_table_propagation" "prod_a_to_prod_rt" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.prod_a.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
# Prod RT → Egress VPC への Static Route (インターネットアクセス集約)
resource "aws_ec2_transit_gateway_route" "prod_to_egress" {
destination_cidr_block= "0.0.0.0/0"
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.egress.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
# Shared Services Route Table (全環境から受信)
resource "aws_ec2_transit_gateway_route_table" "shared" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags= { Name = "rt-shared" }
}
# Egress Route Table
resource "aws_ec2_transit_gateway_route_table" "egress" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags= { Name = "rt-egress" }
}
# Stg / Dev Route Table (同様のパターンで分離)
resource "aws_ec2_transit_gateway_route_table" "stg" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags= { Name = "rt-stg" }
}
resource "aws_ec2_transit_gateway_route_table" "dev" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags= { Name = "rt-dev" }
}
- Prod RT: Prod VPC 群のみ Propagation / Shared RT と Egress RT への Static Route のみ追加 / Stg・Dev RT とは完全分離
- Stg RT: Stg VPC 群のみ / Prod RT とは経路を共有しない / テスト用途なので Shared へのアクセスは Prod と同等
- Dev RT: Dev VPC 群のみ / 開発者の自由度を確保しつつ Prod には絶対に到達させない
- Shared RT: DNS サーバー / ログ集約 / 監査基盤 / CI/CD ランナーを収容 / 全環境 VPC から受信を許可 / Shared から各環境 VPC への通信は原則禁止 (Pull モデル)
- Egress RT: NAT Gateway を持つ Egress VPC のみ / 0.0.0.0/0 の出口集約専用 / インバウンドは ALB・NLB 経由で別途制御
設計原則: 環境間通信は「Shared RT 経由の Pull モデル」に限定する。Prod VPC が直接 Stg VPC に到達できる経路は Route Table に存在させない。
2-2 マルチアカウント RAM 共有 (Resource Access Manager)
TGW は作成したアカウント (Network Account) に属するリソースだ。他のアカウント (Prod Account・Stg Account など) が TGW に Attachment を作成するためには、RAM (Resource Access Manager) による明示的な共有が必要になる。RAM 共有は Organizations 統合と組み合わせることで、OU 単位の一括共有が可能になり、新規アカウント追加時の手動設定を排除できる。
# RAM リソース共有 (Network Account 側)
resource "aws_ram_resource_share" "tgw" {
name = "tgw-share-all-accounts"
allow_external_principals = false
tags = { Name = "ram-tgw-share" }
}
resource "aws_ram_resource_association" "tgw" {
resource_arn = aws_ec2_transit_gateway.main.arn
resource_share_arn = aws_ram_resource_share.tgw.arn
}
# Organizations OU への共有 (個別アカウント指定不要)
resource "aws_ram_principal_association" "org_root" {
principal = "arn:aws:organizations::${var.management_account_id}:organization/${var.org_id}"
resource_share_arn = aws_ram_resource_share.tgw.arn
}
# Accepter 側 (Prod Account) — TGW Attachment 作成
resource "aws_ec2_transit_gateway_vpc_attachment" "prod_to_shared_tgw" {
provider = aws.prod_account
transit_gateway_id = var.shared_tgw_id # Network Account の TGW ID
vpc_id = var.prod_vpc_id
subnet_ids= var.prod_tgw_subnet_ids
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
tags = { Name = "attach-prod-vpc-to-shared-tgw", Env = "prod" }
}
# Network Account 側での Attachment 承認
resource "aws_ec2_transit_gateway_vpc_attachment_accepter" "prod" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.prod_to_shared_tgw.id
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
tags = { Name = "accept-prod-attachment" }
}
# Prod Attachment を Prod RT に紐付け
resource "aws_ec2_transit_gateway_route_table_association" "prod_attach" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment_accepter.prod.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
resource "aws_ec2_transit_gateway_route_table_propagation" "prod_propagate" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment_accepter.prod.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
- 落とし穴 1: 同一リージョン限定 — RAM による TGW 共有は同一リージョン内のアカウント間でのみ有効。クロスリージョンの TGW 共有には RAM は使えず、TGW Peering Attachment を別途設定する必要がある
- 落とし穴 2: 承認フロー必須 (Organizations 統合なしの場合) — Organizations 統合が有効でない場合、Accepter 側アカウントのコンソールでの手動承認が必要。Terraform の
aws_ec2_transit_gateway_vpc_attachment_accepterリソースで自動承認できるが、Terraform State を Network Account 側に集約するか、クロスアカウント Provider を正しく設定しないと State 分裂が起きる - 落とし穴 3: Attachment 数上限の共有制限 — RAM 共有先アカウントで作成した Attachment も Network Account の TGW Quota に積算される。全アカウント合計 5,000 Attachment の上限に注意し、早期に Quota 緩和申請を行うこと
推奨設計: Organizations 統合 + OU 単位共有 + Network Account 集約 Terraform State + aws_ec2_transit_gateway_vpc_attachment_accepter による自動承認の組み合わせで運用コストを最小化する。
2-3 クロスリージョン TGW Peering
マルチリージョン展開では、各リージョンに独立した TGW を構築し、TGW Peering Attachment でリージョン間をブリッジする。クロスリージョン Peering では BGP による経路自動広告はサポートされず、Static Route を手動で設定する必要がある。また、リージョン間のデータ転送料金が発生するため、通信量の試算と通信パターンの最適化が重要になる。
# us-east-1 側 TGW Peering Attachment (ap-northeast-1 の TGW へ接続)
resource "aws_ec2_transit_gateway_peering_attachment" "use1_to_apne1" {
provider = aws.us_east_1
transit_gateway_id= aws_ec2_transit_gateway.use1.id
peer_transit_gateway_id = var.apne1_tgw_id
peer_region = "ap-northeast-1"
peer_account_id= var.apne1_account_id
tags = { Name = "tgw-peer-use1-to-apne1" }
}
# ap-northeast-1 側での Peering 承認
resource "aws_ec2_transit_gateway_peering_attachment_accepter" "apne1_accept" {
provider = aws.ap_northeast_1
transit_gateway_attachment_id = aws_ec2_transit_gateway_peering_attachment.use1_to_apne1.id
tags = { Name = "tgw-peer-apne1-accept" }
}
# us-east-1 側 Prod RT → ap-northeast-1 CIDR への Static Route
resource "aws_ec2_transit_gateway_route" "use1_prod_to_apne1" {
provider = aws.us_east_1
destination_cidr_block= "10.50.0.0/14" # ap-northeast-1 の VPC CIDR 範囲
transit_gateway_attachment_id = aws_ec2_transit_gateway_peering_attachment.use1_to_apne1.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.use1_prod.id
}
# ap-northeast-1 側 Prod RT → us-east-1 CIDR への Static Route (逆方向)
resource "aws_ec2_transit_gateway_route" "apne1_prod_to_use1" {
provider = aws.ap_northeast_1
destination_cidr_block= "10.1.0.0/14" # us-east-1 の VPC CIDR 範囲
transit_gateway_attachment_id = aws_ec2_transit_gateway_peering_attachment_accepter.apne1_accept.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.apne1_prod.id
}
- TGW Peering データ転送料金: us-east-1 ↔ ap-northeast-1 間は約 $0.02/GB (送信側課金)
- 試算例: 月 1TB 転送: 1,000GB × $0.02 = $20/月 (Peering 接続料金 $0.05/h × 720h = $36 別途)
- 試算例: 月 10TB 転送: 10,000GB × $0.02 = $200/月 + 接続料金 $36 = 計 $236/月
- コスト最適化戦略: クロスリージョン通信を必要最小限に絞る設計が必須。ログ・メトリクスデータは各リージョンで完結させ、クロスリージョンは認証・設定データの同期に限定する
- BGP 非対応の注意点: クロスリージョン TGW Peering では動的経路広告がサポートされない。新しい VPC CIDR を追加するたびに両リージョンの Static Route を手動更新する運用コストを設計時点で考慮すること
2-4 Network Manager + VPC Flow Logs 統合監視
TGW を含むネットワーク全体の可視化には AWS Network Manager を活用する。Network Manager はグローバルネットワークを論理的に定義し、TGW・DX・Site-to-Site VPN・SD-WAN デバイスを一元的に登録・監視できる。Route Analyzer 機能により、特定の送信元 IP から宛先 IP への経路が TGW Route Table 上でどのように解決されるかをシミュレーションできる。
# グローバルネットワーク作成
aws networkmanager create-global-network \
--description "Multi-Account Production Network" \
--tags Key=Name,Value=prod-global-network \
--region us-east-1
# TGW をグローバルネットワークに登録
GLOBAL_NETWORK_ID=$(aws networkmanager list-global-networks \
--query "GlobalNetworks[?Description=='Multi-Account Production Network'].GlobalNetworkId" \
--output text --region us-east-1)
aws networkmanager register-transit-gateway \
--global-network-id "$GLOBAL_NETWORK_ID" \
--transit-gateway-arn "arn:aws:ec2:ap-northeast-1:${ACCOUNT_ID}:transit-gateway/${TGW_ID}" \
--region us-east-1
# Route Analyzer で経路確認 (送信元 → 宛先のルート解決シミュレーション)
aws networkmanager start-route-analysis \
--global-network-id "$GLOBAL_NETWORK_ID" \
--source "TransitGatewayAttachmentArn=${PROD_VPC_ATTACH_ARN},IpAddress=10.1.0.10" \
--destination "TransitGatewayAttachmentArn=${SHARED_VPC_ATTACH_ARN},IpAddress=10.100.0.20" \
--region us-east-1
# VPC Flow Logs を S3 + CloudWatch Logs に同時出力 (TGW Flow Logs)
aws ec2 create-flow-logs \
--resource-type TransitGateway \
--resource-ids "$TGW_ID" \
--traffic-type ALL \
--log-destination-type s3 \
--log-destination "arn:aws:s3:::${FLOW_LOGS_BUCKET}/tgw-flow-logs/" \
--log-format '${version} ${account-id} ${tgw-id} ${tgw-attachment-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}'
- トポロジーマップ: TGW を中心に VPC Attachment・DX Gateway・Site-to-Site VPN の接続関係をグラフィカルに表示。接続状態 (UP/DOWN) のリアルタイム確認
- Route Analyzer: 送信元 IP アドレスから宛先 IP アドレスへの経路を TGW Route Table 上でシミュレーション。「なぜこのパケットが届かないか」の調査を数分で完了できる
- イベント監視: Attachment の状態変化・BGP セッションの切断・Route Table の変更を CloudWatch Events で検知し、SNS 経由でアラートを発報
- TGW Flow Logs: VPC Flow Logs の TGW 版。Attachment 単位でのトラフィックパターン分析・不審な通信検知・帯域使用量の把握に活用
- Athena 連携: S3 に出力した TGW Flow Logs を Athena でクエリし、「Prod VPC から Stg VPC への通信が発生していないか」を定期的に検証する Route Table 分離の整合性確認
2-5 TGW Quota 管理 (Attachment 数 / Route Table エントリ上限)
TGW には AWS アカウントおよびリソース単位の Quota (上限) が設定されている。マルチアカウント網では RAM 共有先アカウントの Attachment も Network Account の TGW に積算されるため、Quota 超過は全アカウントのネットワーク接続に影響するサービス断リスクを伴う。Quota 管理は運用初期から計画的に行い、上限の 80% に達した段階で緩和申請を開始することが推奨される。
主要な Quota 値 (2024年時点):
– TGW あたりの VPC Attachment 数: 5,000 (デフォルト 5,000 / 緩和不可の場合あり)
– TGW あたりの Route Table 数: 20 (デフォルト / 緩和申請可能)
– Route Table あたりの静的ルート数: 1,000
– Route Table あたりの動的ルート (Propagation): 10,000
– TGW Peering Attachment 数: 50 (デフォルト / 緩和申請可能)
現在の使用状況を定期的に AWS CLI で確認し、Quota 到達前にキャパシティプランニングを行う。
# TGW の現在の Attachment 数を確認
TGW_ID="tgw-xxxxxxxxxxxxxxxxx"
echo "=== TGW Attachment 一覧 (状態別) ==="
aws ec2 describe-transit-gateway-attachments \
--filters "Name=transit-gateway-id,Values=${TGW_ID}" \
--query "TransitGatewayAttachments[].{State:State,Type:ResourceType,AccountId:ResourceOwnerId}" \
--output table
echo "=== Attachment 総数 ==="
aws ec2 describe-transit-gateway-attachments \
--filters "Name=transit-gateway-id,Values=${TGW_ID}" \
--query "length(TransitGatewayAttachments)" \
--output text
echo "=== Route Table エントリ数確認 ==="
aws ec2 get-transit-gateway-route-table-routes \
--transit-gateway-route-table-id tgw-rtb-xxxxxxxxxxxxxxxxx \
--query "length(Routes)" \
--output text
# Service Quotas API で TGW 関連 Quota を確認
aws service-quotas list-service-quotas \
--service-code vpc \
--query "Quotas[?contains(QuotaName, 'Transit Gateway')].{Name:QuotaName,Value:Value,Adjustable:Adjustable}" \
--output table
- リスク 1: Attachment 追加失敗 — Quota 到達後に新規 VPC Attachment を追加しようとすると API エラーで失敗。新規アカウントのオンボーディングが停止し、事業展開に影響
- リスク 2: Route Table エントリ上限到達 — Propagation によって自動広告されるルートが 10,000 を超えると、新規経路の広告が停止し、通信断が発生。VPC CIDR の細かい分割設計が原因になるケースが多い
- リスク 3: 緩和申請のリードタイム — AWS Service Quota の緩和申請は承認まで 1〜5 営業日かかる場合がある。Quota 超過後に申請しても即時解決しない
- 事前対策 1: 定期的な Quota 使用率監視 — CloudWatch メトリクスで TGW の Attachment 数・Route Table エントリ数を監視し、80% 到達でアラート発報
- 事前対策 2: VPC CIDR の集約設計 — アカウントごとに /16 を 1 つ割り当て、サブネット設計で分割する。/24 を多数広告する設計は Route Table エントリを急増させる
- 事前対策 3: 年次 Quota レビュー — 四半期ごとにアカウント増加計画と現在の Quota 使用率を照合し、必要に応じて事前に緩和申請を行う
- 事前対策 4: マルチ TGW 構成の検討 — 単一 TGW が Quota 上限に近づいた場合、Network Account を複数リージョンに分散するか、大規模アカウント群を別 TGW に分割する設計を事前に検討しておく
TGW の Route Table 分離・RAM 共有・クロスリージョン Peering・Network Manager 統合・Quota 管理の 5 要素を組み合わせることで、20〜100 アカウント規模のマルチアカウント網を本番品質で運用する Transit Gateway 基盤が完成する。次章では PrivateLink を用いたクロスアカウントでのサービス公開と、Interface Endpoint の DNS 解決設計を解説する。
3. PrivateLink 本番運用 — Interface/Gateway/GWLB × クロスアカウント × Private DNS
3-1 Interface vs Gateway vs GWLB Endpoint 選定
VPC Endpoint には3種類あり、用途・コスト・ルーティング方式が異なる。
誤選定すると不要なコストや設計複雑化を招くため、選定基準を明確にしておく。
| 種別 | 対応サービス | コスト | ルーティング方式 | 本番選定基準 |
|---|---|---|---|---|
| Gateway Endpoint | S3 / DynamoDB のみ | 無料 | Route Table追記 (prefix-list) | S3/DynamoDBは第一選択。VPC内DNSに依存しない |
| Interface Endpoint | 100+のAWSサービス・独自サービス | ENI毎に時間課金 + データ転送料 | ENI経由のプライベートIP | Gateway対象外は全てInterface。Private DNS統合が鍵 |
| GWLB Endpoint | Gateway Load Balancer (IDS/IPS/Firewall) | データ転送料のみ | GWLB経由で透過型チェーン | インラインセキュリティアプライアンス導入時に選択 |
- Gateway Endpoint は Route Table変更のみ / ENI不要 / SG設定不要 / 無料の最優先選択肢
- Interface Endpoint は ENI 1個/AZ × サービス × VPC のコストが積み上がる — 使うAZを絞る設計が有効
- GWLB Endpoint はアプライアンス透過挿入専用 — 一般用途での選択はしない
Gateway Endpoint と Interface Endpoint の基本的な Terraform 設定を以下に示す。
コスト最適化の観点から、S3/DynamoDB は必ず Gateway Endpoint を先に設定し、それ以外で必要なサービスのみ Interface Endpoint を追加する。
# Gateway Endpoint (S3 / DynamoDB) — 無料、Route Table追記方式
resource "aws_vpc_endpoint" "s3_gateway" {
vpc_id= var.vpc_id
service_name= "com.amazonaws.${var.region}.s3"
vpc_endpoint_type = "Gateway"
# 対象 Route Table を全サブネット分指定
route_table_ids = concat(
var.private_route_table_ids,
var.public_route_table_ids
)
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = "*"
Action = ["s3:GetObject", "s3:PutObject", "s3:ListBucket"]
Resource = ["arn:aws:s3:::*", "arn:aws:s3:::*/*"]
}]
})
tags = { Name = "ep-s3-gateway", Env = "prod" }
}
resource "aws_vpc_endpoint" "dynamodb_gateway" {
vpc_id= var.vpc_id
service_name= "com.amazonaws.${var.region}.dynamodb"
vpc_endpoint_type = "Gateway"
route_table_ids= var.private_route_table_ids
tags = { Name = "ep-dynamodb-gateway", Env = "prod" }
}
3-2 Endpoint Service 設計 (NLB/GWLB + Acceptance Required)
社内マイクロサービスや共通基盤をクロスアカウントに公開する場合、Endpoint Service (PrivateLink Service Provider) を構成する。
NLB または GWLB をバックエンドに据え、許可管理の設計が本番品質を左右する。
# NLB Endpoint Service + Allowed Principals (Organizations OU)
resource "aws_lb" "service_nlb" {
name= "svc-nlb-prod"
internal = true
load_balancer_type = "network"
subnets= var.private_subnet_ids
enable_cross_zone_load_balancing = true
tags = { Name = "svc-nlb-prod", Env = "prod" }
}
resource "aws_vpc_endpoint_service" "svc" {
acceptance_required = false
network_load_balancer_arns = [aws_lb.service_nlb.arn]
# Organizations OU ARN を Allowed Principals に指定 → 手動承認不要
allowed_principals = [
"arn:aws:iam::*:root", # 全アカウント許可 (OU限定の場合は下記)
# "arn:aws:organizations::123456789012:ou/o-xxxx/ou-xxxx-xxxxxxxx"
]
private_dns_name = "svc.internal.example.com"
tags = { Name = "endpoint-svc-prod" }
}
resource "aws_vpc_endpoint_service_allowed_principal" "ou" {
vpc_endpoint_service_id = aws_vpc_endpoint_service.svc.id
principal_arn = "arn:aws:organizations::123456789012:ou/o-abcdef/ou-abcd-12345678"
}
- Acceptance Required = true: 接続要求を Provider 側が手動承認 → 少数の信頼済アカウントのみ接続させる閉域サービス向け。大規模運用では手作業になるため原則禁止
- Allowed Principals = Organizations OU: OU単位で自動許可 → 新規アカウント追加時も承認不要。本番推奨パターン
- セキュリティ観点: Acceptance Required = false のままAllowed Principalsを空にすると全アカウントからアクセス可能になる — OU/Account ARNを必ず明示設定すること
- PrivateLink経由でも SG/NACLによるネットワーク制御は有効 — 多層防御の観点でSGは必ず設定する
3-3 クロスアカウント PrivateLink (Consumer側/Provider側)
Consumer側 (サービスを利用するアカウント) でのEndpoint作成と、Provider側の許可設定を
Terraformで一元管理するパターン。組織内のサービスメッシュ構築に活用する。
# Consumer側: クロスアカウント Interface Endpoint + Private DNS 解決
data "aws_vpc_endpoint_service" "target_svc" {
service_name = "com.amazonaws.vpce.ap-northeast-1.vpce-svc-xxxxxxxxxxxxxxxxx"
}
resource "aws_vpc_endpoint" "cross_account" {
vpc_id = var.consumer_vpc_id
service_name = data.aws_vpc_endpoint_service.target_svc.service_name
vpc_endpoint_type= "Interface"
subnet_ids = var.consumer_private_subnet_ids
security_group_ids = [aws_security_group.endpoint_sg.id]
# Private DNS を有効化 → サービスFQDNをEndpoint経由で解決
private_dns_enabled = true
tags = { Name = "ep-cross-account-svc", Env = "prod" }
}
resource "aws_security_group" "endpoint_sg" {
name= "endpoint-sg-prod"
vpc_id = var.consumer_vpc_id
ingress {
from_port= 443
to_port = 443
protocol = "tcp"
cidr_blocks = [var.consumer_vpc_cidr]
}
egress {
from_port= 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
- 最小権限の原則: Allowed Principals は呼び出し元Account ARN または OU ARN に限定 — ワイルドカードは原則禁止
- DNS解決: Consumer VPCで
enableDnsHostnames = true+enableDnsSupport = trueが前提条件。片方でも無効だとPrivate DNS解決が失敗する - マルチAZ配置: Endpoint ENIは接続先サービスと同じAZに作成する。AZ不一致はクロスAZデータ転送料が発生し、かつレイテンシが増加する
- SG設計: Endpoint SGのIngressは呼び出し元リソースのSGまたはCIDRに限定。0.0.0.0/0は許可しない
- モニタリング: VPC Flow Logs でEndpoint ENIへのトラフィックを記録 — 異常通信の早期検知に活用
3-4 Private DNS 名前解決の罠
PrivateLinkで最も多いトラブルがDNS解決失敗。Interface Endpointを作成しても
VPC設定やDNS競合によってPublicエンドポイントへルーティングされ続ける事故が多発する。
- 落とし穴①: VPC DNS Resolution 無効化
enableDnsHostnamesまたはenableDnsSupportがfalseの場合、Private DNS が機能しない。
Terraform でenable_dns_hostnames = true+enable_dns_support = trueを明示設定すること - 落とし穴②: Private DNS 名前衝突
同一VPCに同じFQDNを持つEndpointが複数存在すると解決先が不定になる。
Endpoint Serviceのprivate_dns_nameはVPC内でユニークになるよう命名規則を設ける - 落とし穴③: Split-horizon DNS の不整合
Route 53 Private Hosted Zone と Endpoint Private DNS が重複すると優先度が不定。
原則: Endpoint Private DNS を使う場合は Route 53 PHZ での同名レコード定義を禁止 - 落とし穴④: 古いDNSキャッシュ
Endpoint ENI の IPアドレスは変わる場合がある。TTL=60秒以下に設定し、
アプリケーションは DNS キャッシュを短くする (Java: networkaddress.cache.ttl=30)
# nslookup/dig でPrivate DNS名前解決確認
# Interface Endpoint の Private DNS が正しく解決されているか確認
nslookup vpce-svc-xxxxxxxxx.ap-northeast-1.vpce.amazonaws.com
# dig で詳細TTL確認
dig +short vpce-svc-xxxxxxxxx.ap-northeast-1.vpce.amazonaws.com
# Endpoint ENI のプライベートIPアドレス一覧を確認
aws ec2 describe-network-interfaces \
--filters "Name=description,Values=VPC Endpoint Interface*" \
"Name=vpc-id,Values=vpc-xxxxxxxxxxxxxxxxx" \
--query 'NetworkInterfaces[*].[NetworkInterfaceId,PrivateIpAddress,AvailabilityZone]' \
--output table
# S3 Gateway Endpoint 経由の疎通確認
curl -v https://s3.ap-northeast-1.amazonaws.com \
--resolve s3.ap-northeast-1.amazonaws.com:443:$(dig +short s3.ap-northeast-1.amazonaws.com | head -1)
3-5 PrivateLink 上限管理
大規模マルチアカウント環境では、VPC Endpoint数・ENI数・同時接続数が
サービスクォータに達して新規接続不能になるケースがある。事前の容量計画が必要。
| クォータ項目 | デフォルト上限 | 緩和可否 | 監視指標 |
|---|---|---|---|
| VPC当たりInterface Endpoint数 | 50 | 可 | 使用数/上限 > 80%でアラート |
| Endpoint当たりENI数 (AZ数) | AZ数と同数 (最大6) | 不可 | ENI使用率 (10Gbps/ENI) |
| Endpoint Service当たりAZ数 | 最大AZ数 | 不可 | AZ障害時のフェールオーバー確認 |
| 同時接続数/Endpoint | 無制限 (NLBのTCU制限に依存) | NLB側で調整 | ActiveConnectionCount |
- 大規模環境では VPC当たり50上限に注意 — Shared Services VPCに集約してEndpoint数を削減する設計が有効
- Endpoint ENIは帯域 10Gbps/AZ が上限 — ピーク帯域を CloudWatch
BytesProcessedで継続監視 - クォータ緩和は Service Quotas コンソールから申請 — 緩和完了まで数営業日かかるため事前申請を推奨
Interface Endpoint の帯域使用率を定期監視するための CloudWatch アラーム設定を示す。
帯域上限 (10Gbps/AZ) の80%を超えたら通知し、Endpoint 追加を検討するトリガーとする。
# Interface Endpoint の帯域使用率アラーム設定
aws cloudwatch put-metric-alarm \
--alarm-name "endpoint-bandwidth-high" \
--alarm-description "Interface Endpoint bandwidth > 80% of 10Gbps limit" \
--metric-name BytesProcessed \
--namespace AWS/PrivateLinkEndpoints \
--dimensions Name=Endpoint,Value=vpce-xxxxxxxxxxxxxxxxx \
--statistic Sum \
--period 300 \
--evaluation-periods 3 \
--threshold 12000000000 \
--comparison-operator GreaterThanOrEqualToThreshold \
--alarm-actions "arn:aws:sns:ap-northeast-1:123456789012:infra-alerts"
# 接続数監視 (ActiveConnections)
aws cloudwatch put-metric-alarm \
--alarm-name "endpoint-connections-high" \
--alarm-description "Interface Endpoint active connections high" \
--metric-name ActiveConnections \
--namespace AWS/PrivateLinkEndpoints \
--dimensions Name=Endpoint,Value=vpce-xxxxxxxxxxxxxxxxx \
--statistic Average \
--period 60 \
--evaluation-periods 5 \
--threshold 10000 \
--comparison-operator GreaterThanOrEqualToThreshold \
--alarm-actions "arn:aws:sns:ap-northeast-1:123456789012:infra-alerts"
4. Direct Connect 本番運用 — Dedicated/Hosted × LAG × Resilient構成 × BGP
4-1 Dedicated vs Hosted 選定表
Direct Connect には Dedicated Connection (AWS直接提供) と Hosted Connection (パートナー提供) の2種類がある。
帯域要件・調達リードタイム・コスト構造が異なるため、要件に合わせた選定が重要。
| 項目 | Dedicated Connection | Hosted Connection |
|---|---|---|
| 帯域 | 1G / 10G / 100G | 50M〜10G (AWSパートナーが提供) |
| 調達リードタイム | 数週間〜1ヶ月以上 | 数日〜2週間 (パートナー次第) |
| コスト | ポート時間料金 + データ転送料 | パートナー料金体系 (通常割高) |
| 冗長構成 | LAGで複数回線束ねて冗長化可能 | 単独接続のみ (LAG非対応) |
| VIF数 | 最大50 VIF/接続 | 1接続=1 VIF |
| 選定基準 | 大容量・長期利用・本番環境 | 帯域小・短期・パイロット環境 |
- 本番環境で 1Gbps超の帯域が必要な場合は Dedicated 一択
- Hosted は1接続=1 VIFの制約があるため、複数 VIF が必要な場合は Dedicated を選択
- コスト比較は AWS料金計算ツールで Dedicated Port時間料 vs Hosted パートナー料金を試算する
4-2 VIF 種別 (Private/Public/Transit) + LAG
VIF (Virtual Interface) は Direct Connection上の論理インターフェース。
用途に応じて3種類を使い分け、LAG (Link Aggregation Group) で帯域向上と冗長化を実現する。
# Transit VIF + LAG (Link Aggregation Group)
resource "aws_dx_lag" "main" {
name= "dx-lag-prod"
connections_bandwidth = "10Gbps"
location = "EqTY2" # データセンターロケーションコード
force_destroy= false
tags = { Name = "dx-lag-prod", Env = "prod" }
}
resource "aws_dx_connection" "conn1" {
name= "dx-conn-prod-1"
bandwidth = "10Gbps"
location = aws_dx_lag.main.location
}
resource "aws_dx_connection" "conn2" {
name= "dx-conn-prod-2"
bandwidth = "10Gbps"
location = aws_dx_lag.main.location
}
resource "aws_dx_connection_association" "lag_assoc1" {
connection_id = aws_dx_connection.conn1.id
lag_id = aws_dx_lag.main.id
}
resource "aws_dx_connection_association" "lag_assoc2" {
connection_id = aws_dx_connection.conn2.id
lag_id = aws_dx_lag.main.id
}
# Transit VIF: TGW接続専用の VIF
resource "aws_dx_transit_virtual_interface" "transit_vif" {
connection_id = aws_dx_lag.main.id # LAG ID を指定して LAG経由で作成
name = "dx-transit-vif-prod"
vlan = 100
address_family= "ipv4"
bgp_asn = 65000 # オンプレ側 ASN
amazon_address= "169.254.0.1/30"
customer_address = "169.254.0.2/30"
bgp_auth_key = var.bgp_auth_key # BGP MD5認証キー (Secrets Managerから取得)
tags = { Name = "dx-transit-vif-prod" }
}
- Private VIF: VGW (Virtual Private Gateway) 経由で単一VPCに接続。TGWを使わないシンプル構成向け。1 VIF = 1 VPC
- Public VIF: AWSのPublicサービス (S3/DynamoDB/API Gateway等) にDX経由でアクセス。インターネットを経由しないAWSサービスアクセスが目的
- Transit VIF: TGW経由で複数VPCに接続。マルチアカウント・マルチVPC環境ではTransit VIFが唯一の正解。1 Transit VIF で複数VPCへのルーティングが可能
- LAG要件: 複数回線をLAGで束ねるとLACP (802.3ad) で帯域集約・冗長化が実現。ただし同一ロケーション内の冗長化のみで、ロケーション障害には対応しない
4-3 DX Gateway + SiteLink (マルチリージョン接続)
DX Gateway はリージョンをまたいだ VPC/TGW との接続を可能にするグローバルリソース。
SiteLink は DX経由でオンプレ拠点間をAWS Backboneで接続する機能で、ISP回線コストを削減できる。
# DX Gateway + TGW Association
resource "aws_dx_gateway" "main" {
name= "dx-gateway-global"
amazon_side_asn = "64512" # AWS側のプライベート ASN
}
resource "aws_dx_gateway_association" "tgw_assoc_tokyo" {
dx_gateway_id= aws_dx_gateway.main.id
associated_gateway_id = aws_ec2_transit_gateway.main.id
# TGWに広告するプレフィックス (オンプレ → AWSへの経路)
allowed_prefixes = [
"10.0.0.0/8",# VPC CIDRの集約経路
"172.16.0.0/12",
]
}
# SiteLink: オンプレ拠点間をAWS Backbone経由で接続
resource "aws_dx_transit_virtual_interface" "sitelink_vif" {
connection_id = aws_dx_connection.conn1.id
name = "dx-vif-sitelink"
vlan = 200
address_family = "ipv4"
bgp_asn = 65001
# SiteLink を有効化 → 別拠点のDX接続とBackbone経由でルーティング
sitelink_enabled = true
tags = { Name = "dx-vif-sitelink-prod" }
}
# DX Gateway に複数リージョンの TGW を関連付け (マルチリージョン)
resource "aws_dx_gateway_association" "tgw_assoc_osaka" {
provider = aws.ap-northeast-3 # 大阪リージョン
dx_gateway_id= aws_dx_gateway.main.id
associated_gateway_id = var.osaka_tgw_id
allowed_prefixes = ["10.100.0.0/16"] # 大阪VPC CIDR
}
- SiteLink とは: 異なるロケーションに接続されたDX回線間でAWS Backboneを転送路として使用する機能
- ユースケース: 東京拠点 ↔ 大阪拠点 の拠点間通信をDX + AWS Backbone経由で実現。専用ISP拠点間バックホール回線が不要になりコスト削減
- 設定方法: Transit VIF で
sitelink_enabled = trueに設定。Transit VIF のみ対応 (Private VIF / Public VIF は非対応) - コスト: SiteLink有効時はデータ転送料にSiteLink追加料金が発生 — 既存拠点間回線との費用比較を必ず実施
- 制約: 接続ロケーション間のレイテンシはAWS Backbone依存。RTT要件が厳格な用途は実測値を確認すること
4-4 Resilient構成 (Maximum/High/Development)
Direct Connect の最大の弱点は物理回線障害。適切なResiliency設計なしに本番利用すると
ロケーション障害時に全通信断が発生する。AWS推奨の構成パターンを採用する。
| 構成 | 冗長レベル | SLA目安 | 用途 |
|---|---|---|---|
| Single Location 1回線 | なし | — | 開発・検証のみ。本番禁止 |
| Single Location 2回線 (LAG) | ロケーション内冗長 | 99.9% | 小規模本番 (ロケーション障害は想定外) |
| Multi-Location 2回線 (High Resiliency) | 物理ロケーション冗長 | 99.99% | 本番推奨構成 |
| Multi-Location 4回線 (Maximum Resiliency) | 複数ロケーション × 複数回線 | 99.999% | 金融・製造等ミッションクリティカル |
- Single Location → Maximum Resiliency 移行手順
- Step1: 新規ロケーション (異なる物理設備) でDX Dedicated Connectionを発注 (リードタイム: 4〜8週間)
- Step2: 新ロケーションで Transit VIF を作成し、DX Gatewayに接続 — 既存VIFと並行稼働
- Step3: BGP Local_Pref / AS_PATH Prepending で新旧回線の優先度を設定しトラフィックシフト検証
- Step4: CloudWatch で双方のBGP Stateを監視 —
ConnectionStateがavailableであることを継続確認 - Step5: DX + Site-to-Site VPN バックアップを同時設定 (下記参照)
DX障害時のフェールオーバーは Site-to-Site VPN をバックアップとして構成する。
BFD (Bidirectional Forwarding Detection) で障害を高速検知し、BGP自動フェールオーバーを実現する。
# DX + Site-to-Site VPN バックアップ構成の確認コマンド
# BGP セッション状態確認 (DX側)
aws directconnect describe-virtual-interfaces \
--query 'virtualInterfaces[*].[virtualInterfaceId,bgpPeers[*].bgpStatus]' \
--output table
# VPN トンネル状態確認 (バックアップVPN)
aws ec2 describe-vpn-connections \
--filters "Name=state,Values=available" \
--query 'VpnConnections[*].[VpnConnectionId,VgwTelemetry[*].Status]' \
--output table
# CloudWatch メトリクス: DX BGP State
aws cloudwatch get-metric-statistics \
--namespace AWS/DX \
--metric-name ConnectionBpsIngress \
--dimensions Name=ConnectionId,Value=dxcon-xxxxxxxxx \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 300 \
--statistics Average \
--output table
4-5 BGP 本番運用 (Community Tagging / ECMP / Multi-Tunnel)
BGPはDirect ConnectとVPNの両方で使用するルーティングプロトコル。
Community Tagを活用した経路制御とECMPによる帯域分散が本番運用の品質を決める。
# BGP Community Tag 設定例 (オンプレルータ側設定)
# AWS Well-Known BGP Community Tags (受信 → AWSへの広告経路に付与)
# 7224:8100 — この経路を同一AWSリージョン内のみに広告
# 7224:8200 — この経路を同一大陸内のみに広告
# 7224:9100 — ローカルプレファレンスを高に設定 (プライマリ経路)
# 7224:9200 — ローカルプレファレンスを中に設定
# 7224:9300 — ローカルプレファレンスを低に設定 (バックアップ経路)
# Cisco IOS 設定例 (プライマリDX: LP=200 / バックアップVPN: LP=100)
# route-map SET_LP_HIGH permit 10
# set local-preference 200
# set community 7224:9100
# !
# route-map SET_LP_LOW permit 10
# set local-preference 100
# set community 7224:9300
# AS_PATH Prepending でプライマリ/バックアップを制御
# neighbor <AWS_BGP_IP> route-map PREPEND_OUT out
# route-map PREPEND_OUT permit 10
# set as-path prepend 65000 65000# 2回プリペンドでバックアップ経路として広告
# ECMP 確認: 等コスト経路が複数存在する場合のトラフィック分散
aws ec2 describe-transit-gateway-route-tables \
--transit-gateway-route-table-id tgw-rtb-xxxxxxxxxxxxxxxxx \
--query 'TransitGatewayRouteTables[*]' \
--output json
- MD5認証: BGP MD5認証キーを必ず設定 — 未設定はBGPセッションハイジャックリスク
- BFD (Bidirectional Forwarding Detection): DX上でBFDを有効化すると300ms以下でリンク障害を検知可能。BGP keepalive (通常30秒) より圧倒的に高速なフェールオーバーが実現する
- Community Tagging:
7224:9100(プライマリ) /7224:9300(バックアップ) を組み合わせてActive-Standby構成を実現 - ECMP制限: TGW上のECMP (等コストマルチパス) は最大4経路まで。それ以上はBGPで経路絞り込みが必要
- BGP Prefix広告制限: AWS側からオンプレへの広告は Transit VIF で最大200プレフィックス。VPC数が多い場合は集約経路を広告する設計が必要
BGP詳細設定・オンプレルータ機種別設定例・VPN Multi-Tunnelの帯域拡張手法については、
Direct Connect + VPN ハイブリッド接続専門編 で詳しく解説している。
冗長構成のケーススタディや障害シナリオ別のフェールオーバー設計も同記事を参照されたい。
5. VPC Peering vs Site-to-Site VPN — 選定基準 × BGP × Accelerated VPN
VPC Peeringは「2VPC間の直接低レイテンシ接続」に特化した仕組みであり、オンプレミスへのルーティング(推移的転送)は設計上不可能だ。一方、Site-to-Site VPNはオンプレミスや他クラウドとのIPSec暗号化トンネルを構成し、BGP動的経路制御でフェールオーバーを自動化する。本セクションではそれぞれの特性・限界を整理し、Transit Gatewayを含む三方式の選定基準を確立する。
5-1. VPC Peering 特性と限界
VPC Peeringは、同一リージョン・Cross-Region・Cross-Accountを問わず2つのVPC間にプライベートネットワークを直接接続する仕組みだ。AWSの内部インフラを通じたルーティングのため、インターネットを経由せず低レイテンシ・高スループットが実現できる。
VPC Peeringの基本特性:
| 特性 | 詳細 |
|---|---|
| 接続形態 | 1:1ピアリング(インターネット非経由) |
| サポート範囲 | 同一アカウント / Cross-Account / Cross-Region |
| 推移的転送 | 不可(A-B-C PeeringでもAからCには到達不可) |
| 帯域上限 | なし(VPC間フルスループット) |
| レイテンシ | 同一リージョン: 最低 / Cross-Region: リージョン間距離に依存 |
| CIDR重複 | 不可(Peeringリクエスト時点でエラー) |
| Security Group参照 | 同一リージョンのみ可 / Cross-Regionは不可 |
| VPN / インターネット経由 | 不可(Peer先VPC経由の外部ルーティングは禁止) |
VPC Peeringは最もシンプルな接続方式だが、Non-Transitive(推移不可)という根本的な制約が大規模環境での利用を難しくする。VPC AとBをPeering、BとCをPeeringしても、AからCへは直接通信できない。AとCを接続するには別途A-CのPeeringが必要であり、VPC数が増えるほど必要なPeering数が爆発的に増加する。
- VPC数が増えるほど必要なPeering数は二次関数的に増加する
- 5 VPC = 10本 / 10 VPC = 45本 / 20 VPC = 190本
- 各Peeringにつき送受信両方向のRoute Table設定が必要 → Route Table肥大化
- Security GroupのPeered VPC参照はCross-Regionで不可能 → アクセス制御が複雑化
- VPN・インターネット経由の推移的ルーティングはPeer先VPCでは動作しない
- 結論: 3 VPC以上の相互接続はTransit Gateway Hub-and-Spokeへの移行が必須
VPC Peeringの作成にはRequester(接続申請側)とAccepter(承認側)の2ステップが必要だ。Cross-Accountの場合は承認側のアカウントで明示的な承認アクションが必要になる。Terraformでは双方向のRoute Tableエントリを忘れると片方向通信になるため注意が必要だ。
# VPC Peering Connection(Requester側)
resource "aws_vpc_peering_connection" "prod_to_shared" {
vpc_id = aws_vpc.prod.id
peer_vpc_id= aws_vpc.shared.id
peer_owner_id = var.shared_account_id # Cross-Accountの場合
peer_region= var.shared_region# Cross-Regionの場合
auto_accept= false# Cross-Accountは手動承認必須
tags = {
Name = "prod-to-shared-peering"
Side = "Requester"
}
}
# Peering承認(Shared Account側 / Cross-Account Provider使用)
resource "aws_vpc_peering_connection_accepter" "shared_accept" {
provider= aws.shared
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_shared.id
auto_accept= true
tags = {
Name = "shared-accept-prod-peering"
Side = "Accepter"
}
}
# Prod VPC → Shared VPC へのルート(Prod側Route Table)
resource "aws_route" "prod_to_shared" {
route_table_id= aws_route_table.prod_private.id
destination_cidr_block = var.shared_vpc_cidr # 例: 10.1.0.0/16
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_shared.id
}
# Shared VPC → Prod VPC へのルート(Shared側Route Table)
# 双方向設定必須: 片方だけではICMPは通るがTCPが成立しない
resource "aws_route" "shared_to_prod" {
provider= aws.shared
route_table_id= aws_route_table.shared_private.id
destination_cidr_block = var.prod_vpc_cidr # 例: 10.0.0.0/16
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_shared.id
}
# DNS解決を有効化(VPC Peering経由でPrivate DNS名を解決)
resource "aws_vpc_peering_connection_options" "prod_side" {
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_shared.id
requester {
allow_remote_vpc_dns_resolution = true
}
}
resource "aws_vpc_peering_connection_options" "shared_side" {
provider= aws.shared
vpc_peering_connection_id = aws_vpc_peering_connection.prod_to_shared.id
accepter {
allow_remote_vpc_dns_resolution = true
}
}
- VPC Peeringの前提条件: 接続する2つのVPCのCIDRブロックが重複してはならない
- 10.0.0.0/16 同士をPeeringしようとするとリクエスト送信時点でエラー
- 解決策はVPC再作成(既存VPCのCIDR変更は不可)→ 移行コストが膨大になる
- IPv6デュアルスタック構成でもIPv4 CIDRの重複は許容されない
- 予防策: AWS VPC IPAMでアカウント/OU単位にCIDRプールを事前割り当て → 重複ゼロ保証
- Organizations SCPでVPC作成時のCIDRレンジを強制割り当てることも有効
5-2. Site-to-Site VPN 本番運用
AWS Site-to-Site VPNはオンプレミスネットワークとAWS VPCをIPSec暗号化トンネルで接続する。Customer Gateway(オンプレ側のルータ/ファイアウォール)とVirtual Private Gateway(VPC側の終端)またはTransit Gatewayでトンネルを2本(冗長)確立し、BGPまたはスタティックルートで経路を広告する。
Site-to-Site VPN 冗長アーキテクチャ:
オンプレミスAWS
┌────────────────────────┐┌──────────────────────┐
│ Primary Customer│ IPSec Tunnel1 │ Virtual Private│
│ Gateway (ISP-A) ─── │───────────────│─►Gateway (VGW) │
│ 203.0.113.10 ─── ─│───────────────│─► or │
│ Tunnel2 │ TGW VPN Attachment│
│ Secondary Customer ││ │
│ Gateway (ISP-B) ─── │───────────────│─►BGP経路自動フェール │
│ 203.0.113.20 ─── ─│───────────────│─►オーバー │
└────────────────────────┘└──────────────────────┘
BGP AS: 65000BGP AS: 64512
AWS側は各Customer Gatewayに対して自動的に2本のトンネルを作成する。これにより合計4本のIPSecトンネルで完全冗長構成が実現する。BGPを使えば障害Tunnelを自動検知して経路を切り替えるため、手動介入なしに継続運用が可能だ。
# Customer Gateway(Primary: ISP-A回線)
resource "aws_customer_gateway" "primary" {
bgp_asn = 65000# オンプレBGP AS番号
ip_address = "203.0.113.10"# Primary ISP Public IP
type = "ipsec.1"
tags = {
Name = "on-premises-cgw-primary"
ISP = "ISP-A"
}
}
# Customer Gateway(Secondary: ISP-B回線 / 異なる物理機器推奨)
resource "aws_customer_gateway" "secondary" {
bgp_asn = 65000
ip_address = "203.0.113.20"# Secondary ISP Public IP
type = "ipsec.1"
tags = {
Name = "on-premises-cgw-secondary"
ISP = "ISP-B"
}
}
# Virtual Private Gateway(VPC終端)
resource "aws_vpn_gateway" "main" {
vpc_id = aws_vpc.prod.id
amazon_side_asn = 64512# AWS側BGP AS番号
tags = {
Name = "prod-vgw"
}
}
# Site-to-Site VPN(Primary CGW + BGP動的経路)
resource "aws_vpn_connection" "primary" {
vpn_gateway_id= aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.primary.id
type = "ipsec.1"
static_routes_only = false # BGP使用(false=BGP動的経路)
# IKE/IPSecパラメータ(本番推奨: IKEv2 + AES256 + SHA2-256)
tunnel1_ike_versions = ["ikev2"]
tunnel1_phase1_encryption_algorithms = ["AES256"]
tunnel1_phase1_integrity_algorithms = ["SHA2-256"]
tunnel1_phase1_dh_group_numbers= [20]
tunnel1_phase2_encryption_algorithms = ["AES256-GCM-16"]
tunnel1_phase2_integrity_algorithms = ["SHA2-256"]
tunnel1_phase2_dh_group_numbers= [20]
tunnel1_rekey_margin_time_seconds = 540
tunnel1_dpd_timeout_seconds = 30
tunnel1_dpd_timeout_action = "restart"
tunnel2_ike_versions = ["ikev2"]
tunnel2_phase1_encryption_algorithms = ["AES256"]
tunnel2_phase1_integrity_algorithms = ["SHA2-256"]
tunnel2_phase1_dh_group_numbers= [20]
tunnel2_phase2_encryption_algorithms = ["AES256-GCM-16"]
tunnel2_phase2_integrity_algorithms = ["SHA2-256"]
tunnel2_phase2_dh_group_numbers= [20]
tunnel2_rekey_margin_time_seconds = 540
tunnel2_dpd_timeout_seconds = 30
tunnel2_dpd_timeout_action = "restart"
tags = {
Name = "prod-vpn-primary"
Priority = "primary"
}
}
# Site-to-Site VPN(Secondary CGW: 完全冗長)
resource "aws_vpn_connection" "secondary" {
vpn_gateway_id= aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.secondary.id
type = "ipsec.1"
static_routes_only = false
tunnel1_ike_versions = ["ikev2"]
tunnel1_phase1_encryption_algorithms = ["AES256"]
tunnel1_phase1_integrity_algorithms = ["SHA2-256"]
tunnel1_phase1_dh_group_numbers= [20]
tunnel1_phase2_encryption_algorithms = ["AES256-GCM-16"]
tunnel1_phase2_dh_group_numbers= [20]
tunnel2_ike_versions = ["ikev2"]
tunnel2_phase1_encryption_algorithms = ["AES256"]
tunnel2_phase1_integrity_algorithms = ["SHA2-256"]
tunnel2_phase1_dh_group_numbers= [20]
tunnel2_phase2_encryption_algorithms = ["AES256-GCM-16"]
tunnel2_phase2_dh_group_numbers= [20]
tags = {
Name = "prod-vpn-secondary"
Priority = "secondary"
}
}
# BGP経路をRoute Tableに自動伝播
resource "aws_vpn_gateway_route_propagation" "prod_private" {
vpn_gateway_id = aws_vpn_gateway.main.id
route_table_id = aws_route_table.prod_private.id
}
- BGP動的経路(推奨): Tunnel障害時に自動でセカンダリTunnelへ切替。Route Table手動変更不要。BGP Community Taggingで経路優先制御も可能
- Static Route(非推奨): 最大10経路という上限がある。Tunnel障害時に自動切替なし → 手動Route Table変更が必要。障害時間が長くなる
- Customer Gateway冗長化(必須): 同一CGW機器の2Tunnel冗長だけでは物理障害・ISP障害をカバーできない。異なる物理機器+異なるISP回線で2台目CGWが必須
- Active-Active構成: Primary/Secondary双方でBGP経路広告 → ECMP等コストで帯域倍増。障害時は自動的に正常Tunnelへ収束
- DPD(Dead Peer Detection)設定: timeout=30秒、action=restartでTunnel自動再確立。デフォルト設定のままにしない
VPN Tunnel状態確認コマンド(運用時の基本確認):
# VPN Connection一覧とTunnel状態を表形式で表示
aws ec2 describe-vpn-connections \
--filters "Name=state,Values=available" \
--query 'VpnConnections[*].{
ID:VpnConnectionId,
State:State,
CGW:CustomerGatewayId,
T1_Status:VgwTelemetry[0].Status,
T1_Routes:VgwTelemetry[0].AcceptedRouteCount,
T2_Status:VgwTelemetry[1].Status,
T2_Routes:VgwTelemetry[1].AcceptedRouteCount
}' \
--output table
# 特定VPN接続の詳細情報(BGP受信経路数を含む)
VPN_ID="vpn-0123456789abcdef0"
aws ec2 describe-vpn-connections \
--vpn-connection-ids "$VPN_ID" \
--query 'VpnConnections[0].VgwTelemetry[*].{
OutsideIP:OutsideIpAddress,
Status:Status,
StatusMsg:StatusMessage,
LastChange:LastStatusChange,
AcceptedRoutes:AcceptedRouteCount
}' \
--output table
# CloudWatch TunnelState メトリクス取得(1=UP, 0=DOWN)
aws cloudwatch get-metric-statistics \
--namespace AWS/VPN \
--metric-name TunnelState \
--dimensions Name=VpnId,Value="$VPN_ID" \
--start-time "$(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--period 300 --statistics Average --output table
5-3. Accelerated VPN(Global Accelerator経由)
Accelerated Site-to-Site VPNは、通常のVPNトラフィックがインターネットを経由するのに対し、AWS Global Acceleratorのエッジネットワーク経由でAWSバックボーンに最短距離で入線させる仕組みだ。Transit Gateway VPN Attachmentでのみ利用可能であり、Virtual Private Gateway(VGW)経由では使用できない。
通常VPN: オンプレ → [公衆インターネット] → AWSリージョン VGW
Accelerated: オンプレ → 最寄りGA Edge → [AWSバックボーン] → AWSリージョン TGW
- レイテンシ改善効果: 最寄りのGlobal Accelerator Edgeへ接続してインターネット上のホップ数を削減。日本→北米接続で10〜30ms程度の改善事例あり
- 利用前提条件: Transit Gateway VPN Attachment経由必須。Virtual Private Gateway(VGW)経由では利用不可
- 追加コスト: Global Acceleratorのデータ転送料が別途発生($0.015/GB程度)。VPN自体の時間料金に上乗せ
- 採用基準: SLAに影響するレイテンシ遅延がある本番システム / 地理的に離れた拠点接続(日本-欧米間など)/ VoIP・リアルタイム通信が通るVPN
- 不要なケース: 同一リージョン内オンプレ接続(東京オフィス-東京リージョン等)/ バックアップ用途・夜間バッチのみ通るVPN
- 静的Anycast IP: GA EdgeのIPは固定。オンプレ側ファイアウォールでの許可リスト管理が容易になる
# Transit Gateway(Accelerated VPN はTGW経由必須)
resource "aws_ec2_transit_gateway" "main" {
description= "Production Transit Gateway"
amazon_side_asn = 64512
default_route_table_association = "disable"
default_route_table_propagation = "disable"
tags = {
Name = "prod-tgw"
}
}
# Customer Gateway(Accelerated VPN用)
resource "aws_customer_gateway" "accelerated" {
bgp_asn = 65000
ip_address = "203.0.113.10" # オンプレルータPublic IP
type = "ipsec.1"
tags = {
Name = "on-premises-cgw-accelerated"
}
}
# Accelerated Site-to-Site VPN(TGW VPN Attachment + enable_acceleration)
resource "aws_vpn_connection" "accelerated" {
transit_gateway_id = aws_ec2_transit_gateway.main.id# TGW経由必須
customer_gateway_id = aws_customer_gateway.accelerated.id
type = "ipsec.1"
static_routes_only = false# BGP使用
enable_acceleration = true # Global Accelerator有効化
# IKEv2 + AES256 推奨設定
tunnel1_ike_versions = ["ikev2"]
tunnel1_phase1_encryption_algorithms = ["AES256"]
tunnel1_phase1_integrity_algorithms = ["SHA2-256"]
tunnel1_phase1_dh_group_numbers= [20]
tunnel1_phase2_encryption_algorithms = ["AES256-GCM-16"]
tunnel1_phase2_dh_group_numbers= [20]
tunnel1_dpd_timeout_action = "restart"
tunnel2_ike_versions = ["ikev2"]
tunnel2_phase1_encryption_algorithms = ["AES256"]
tunnel2_phase1_integrity_algorithms = ["SHA2-256"]
tunnel2_phase1_dh_group_numbers= [20]
tunnel2_phase2_encryption_algorithms = ["AES256-GCM-16"]
tunnel2_phase2_dh_group_numbers= [20]
tunnel2_dpd_timeout_action = "restart"
tags = {
Name = "prod-accelerated-vpn"
Accelerated = "true"
}
}
# TGW VPN Attachment のRoute Table関連付け
resource "aws_ec2_transit_gateway_route_table_association" "vpn" {
transit_gateway_attachment_id = aws_vpn_connection.accelerated.transit_gateway_attachment_id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
5-4. Peering vs VPN vs TGW 選定マトリクス
3方式の特性を横断的に比較することで、要件に対して最適な方式を選択できるようになる。特に「推移性の必要/不要」と「オンプレミス接続の有無」の2軸が選定において最も重要だ。
| 評価軸 | VPC Peering | Site-to-Site VPN | Transit Gateway |
|——–|————-|——————|—————–|
| 接続形態 | VPC間 1:1 直接 | オンプレ〜AWS間 | Hub-and-Spoke |
| 推移的転送 | 不可 | 不可(VGW単体) | 可能 |
| スケーラビリティ | O(N²)で爆発 | 接続数に比例 | O(N)で線形 |
| オンプレ接続 | 不可 | 可能 | 可能(VPN Attachment) |
| CIDR制約 | 重複不可 | なし | なし |
| 暗号化 | なし(VPC内通信) | IPSec必須 | 任意 |
| レイテンシ | 最低(最速) | VPN overhead | 経路最適化 |
| BGP対応 | なし | あり | あり |
| 時間料金 | なし | $0.05/h/接続 | $0.05/h/Attachment |
| データ転送料 | リージョン間のみ | 通常のデータ転送料 | リージョン間+TGW料 |
| 管理複雑度 | VPC数増で爆発 | CGW設定必要 | 一元管理 |
| 推奨シーン | 特定2VPC低レイテンシ | オンプレ単拠点接続 | 3VPC以上/マルチ拠点 |
5-5. BGP Community Tagging と Multi-Tunnel ECMP
BGPを使ったSite-to-Site VPNでは、Community Taggingで経路の優先度を制御し、ECMP(Equal-Cost Multi-Path)で複数Tunnelを並列利用して帯域を増強できる。本番環境でPrimary/Secondary経路を明示的に制御し、メンテナンス時に経路を安全に切り替えるために必須の知識だ。
# オンプレルータ(Cisco IOS設定例)での BGP Community Tag設定
# Community 7224:8000 = ローカル優先度MAX → このTunnelを最優先で使用
# Community 7224:7200 = ローカル優先度通常 → フォールバック経路
# Community 7224:9300 = この経路を広告しない → メンテ時の経路撤退に使用
# Primary Tunnel向け: 最高優先度を付与
route-map SET-PRIORITY permit 10
set community 7224:8000
# Secondary Tunnel向け: 通常優先度(フォールバック)
route-map SET-LOW-PRIORITY permit 10
set community 7224:7200
# BGP Neighbor設定(各Tunnelに異なるCommunityを適用)
router bgp 65000
neighbor 169.254.10.1 route-map SET-PRIORITY out# Primary Tunnel
neighbor 169.254.20.1 route-map SET-LOW-PRIORITY out# Secondary Tunnel
# ECMP設定: 同コスト経路を並列利用(帯域最大化)
# 全TunnelにEqualコストを設定する場合は同じCommunityを付与
router bgp 65000
maximum-paths 4 # 最大4経路ECMP
neighbor 169.254.10.1 route-map SET-PRIORITY out
neighbor 169.254.20.1 route-map SET-PRIORITY out # 同コスト=ECMP対象
# 障害時動作確認: TunnelのBGP Session状態確認
show ip bgp summary | grep 169.254
show ip route bgp | grep 10.0.0.0
- ECMPとは: 等コスト複数経路(Equal-Cost Multi-Path)を並列利用してトラフィックを分散する機能
- VPN+TGWでのECMP: Transit GatewayはデフォルトでECMPをサポート。同コストのVPN Tunnelを自動ロードバランス
- 帯域の理論値: VPN Tunnel 1本 = 最大1.25Gbps → ECMP 4本で最大5Gbps
- ECMP有効化条件: BGPで同じAS-PATHコストの経路を複数Tunnelから広告すること(等コスト=ECMPの前提)
- フローベース分散: TCPフローを単位として各Tunnelに振り分け。1フローが複数Tunnelに分割されることはない
- 監視ポイント: CloudWatch TunnelDataIn/DataOutで各Tunnel使用率を確認し、Tunnel間偏りがあればBGP設定で均等化する
flowchart TD
A([接続要件を整理する]) --> B{オンプレミス接続が必要?}
B -- はい --> C{帯域・SLA要件}
B -- いいえ --> D{接続するVPC数}
C -- 高帯域 1Gbps+ / 99.99%以上 --> E[Direct Connect\nMulti-Location冗長構成]
C -- 通常帯域 / 99.9% --> F{地理的距離が遠い?}
F -- はい / 海外拠点 --> G[Accelerated Site-to-Site VPN\n+ TGW Attachment\n+ BGP + ECMP\n+ Customer Gateway冗長]
F -- いいえ / 国内拠点 --> H[Site-to-Site VPN\n+ TGW Attachment\n+ BGP動的経路\n+ Customer Gateway冗長]
D -- 2 VPC のみ --> I{CIDR重複がある?}
D -- 3 VPC 以上 --> J[Transit Gateway\nHub-and-Spoke構成]
D -- 将来増加見込み --> J
I -- あり --> K[VPC再設計必須\nIPAM導入でCIDR整理\n→ 整理後にPeering]
I -- なし --> L{低レイテンシが最優先?}
L -- はい --> M[VPC Peering\n双方向Route Table設定\nDNS解決有効化]
L -- いいえ --> N{将来的にVPC追加の予定?}
N -- あり --> J
N -- なし --> M
J --> O{TGWにオンプレ接続も束ねる?}
O -- はい --> P[TGW VPN Attachment\n+ Direct Connect Transit\n+ BGP Community Tagging]
O -- いいえ --> Q[TGW VPC Attachmentのみ\nRoute Table分離]
G --> R[BGP Community Tagging設定\n+ Multi-Tunnel ECMP\n+ CloudWatch監視]
H --> R
R --> S([実装完了\nTunnel状態 / BGP Session\nCloudWatchアラート設定])
E --> S
M --> S
P --> S
Q --> S
K --> M
以上が §5「VPC Peering vs Site-to-Site VPN」の全解説だ。VPC Peeringのシンプルさと低レイテンシは2VPC間接続では最強だが、CIDR重複禁止・Non-Transitiveという根本制約が3VPC以上では致命的になる。Site-to-Site VPNはBGP動的経路とCustomer Gateway冗長化を組み合わせることで本番耐久性を持つオンプレ接続を実現し、Accelerated VPNで海外拠点のレイテンシを最適化できる。3方式の選定マトリクスと判断フローを軸に、要件に応じた最適構成を選択せよ。
6. 詰まりポイント7選 — マルチアカウント網本番運用の地雷とフィックス
マルチアカウント構成のネットワーク本番運用では、単一アカウントでは発生しない複合的な問題が頻発する。
本セクションでは、実際の本番環境で多数報告される7つの詰まりポイントを取り上げ、症状・原因・解決策を体系的に整理する。
各ポイントにはTerraformコードまたはCLIコマンドによる具体的な対処法を示す。
6-1. TGW Route Table 単一化 — 環境間通信全開放によるセグメント設計崩壊
症状
- Dev環境からProd環境のRDSやECSサービスへ直接疎通できてしまう
- セキュリティ要件「本番/開発分離」が実質無効化されている
aws ec2 describe-transit-gateway-route-tablesで確認すると、全VPCが同一Route Tableに紐付いている
原因
Transit Gatewayを構築した際に、デフォルトのRoute Tableを使い続けたまま全AttachmentをAssociateしてしまうパターンが多い。
全Attachmentが同一Route Tableで全Propagationを受け入れる状態になると、Prod/Dev/Shared全てのVPC間でルートが交換され、意図しないクロス環境通信が発生する。
解決策: 環境別Route Table分離 + Association/Propagation再設計
既存環境にTerraformを適用する場合は、先にterraform importで既存Route Tableを取り込む。
# 既存 Route Table の確認
aws ec2 describe-transit-gateway-route-tables \
--filters "Name=transit-gateway-id,Values=tgw-xxxxxxxxxx" \
--query "TransitGatewayRouteTables[*].{Id:TransitGatewayRouteTableId,Default:DefaultAssociationRouteTable}" \
--output table
# Prod専用 Route Table — Shared と Egress からのみ Propagation を受け入れる
resource "aws_ec2_transit_gateway_route_table" "prod" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags = { Name = "tgw-rt-prod" }
}
resource "aws_ec2_transit_gateway_route_table_association" "prod" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.prod.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
resource "aws_ec2_transit_gateway_route_table_propagation" "shared_to_prod" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.shared.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
# Dev → Prod への Propagation は意図的に定義しない
デフォルト Route Table の「Default Association Route Table」フラグを外し忘れると、新規 Attachment が自動的にデフォルト RT に紐付く。Terraform 管理外で手動追加した Attachment が設計を崩壊させるため、
default_route_table_association = "disable" を TGW 本体に設定し、全 Association を明示的に Terraform で管理すること。6-2. PrivateLink 許可リスト破綻 — Allowed Principals 未設定によるサービス停止
症状
- ConsumerアカウントでInterface Endpointを作成しても「Available」状態にならない
- Providerサービス側でAcceptance Requiredが有効なまま、Allowed Principalsが空欄
- エンドポイント接続リクエストがPending状態で停滞し、サービス呼び出しがタイムアウト
原因
Acceptance Required = true に設定したEndpoint Serviceに対して、許可するPrincipal(AWSアカウントやOUのARN)を登録しないまま運用を開始するケースが多い。
手動承認フローを想定して構築したが、Consumers側の開発チームが先に接続を試みてしまい、承認待ちのリクエストが積み上がる。
解決策: aws:PrincipalOrgID条件キーでOrg全体またはOU単位を一括許可
resource "aws_vpc_endpoint_service" "api" {
acceptance_required = false # Org内は自動承認に変更
network_load_balancer_arns = [aws_lb.api.arn]
allowed_principals = [
"arn:aws:organizations::123456789012:ou/o-xxxx/ou-xxxx-xxxxxxxx", # 許可OU
]
tags = { Name = "api-endpoint-service" }
}
# 既存 Endpoint Service への Allowed Principals 追加 (CLI)
aws ec2 modify-vpc-endpoint-service-permissions \
--service-id vpce-svc-xxxxxxxxxx \
--add-allowed-principals "arn:aws:iam::111122223333:root"
# 現在 Pending 状態のリクエストを確認・承認
aws ec2 describe-vpc-endpoint-connections \
--filters "Name=vpc-endpoint-state,Values=pendingAcceptance"
aws ec2 accept-vpc-endpoint-connections \
--service-id vpce-svc-xxxxxxxxxx \
--vpc-endpoint-ids vpce-xxxxxxxxxx
Acceptance Required = true のままにすると、新規 Consumer が追加されるたびに手動承認が必要になる。Organizationsを利用している場合は aws:PrincipalOrgPaths 条件キーでOU階層に基づく自動許可を設定し、手動承認ステップを廃止することが推奨される。Allowed Principals は空のままでは誰も接続できない — デフォルト動作を誤解しているチームが多い。6-3. DX Single Location 回線断 — Resilient構成未整備によるオンプレフルダウン
症状
- Direct Connectの物理障害発生時にオンプレミス→AWS間の通信が完全断
- VPN Failoverも未設定のため、復旧まで数時間〜数日を要する
- CloudWatchのBGP Session Upメトリクスがアラームを発火するが、自動切替が発動しない
原因
コスト削減を優先してSingle Location/Single Connection構成を採用し、冗長化を後回しにしたケースが多い。
VPN Failoverを「あとで設定する」と判断しても、本番稼働が始まると変更に慎重になり、未整備のまま障害を迎えてしまう。
解決策: Maximum Resilience 構成 + Site-to-Site VPN 自動Failover
# DX Gateway — 複数の仮想インターフェイスを束ねる
resource "aws_dx_gateway" "main" {
name= "dxgw-main"
amazon_side_asn = 64512
}
# Location A の Virtual Interface
resource "aws_dx_private_virtual_interface" "loc_a" {
connection_id = var.dx_connection_id_location_a
name = "vif-location-a"
vlan = 101
address_family= "ipv4"
bgp_asn = 65000
dx_gateway_id = aws_dx_gateway.main.id
}
# Location B の Virtual Interface (冗長)
resource "aws_dx_private_virtual_interface" "loc_b" {
connection_id = var.dx_connection_id_location_b
name = "vif-location-b"
vlan = 102
address_family= "ipv4"
bgp_asn = 65000
dx_gateway_id = aws_dx_gateway.main.id
}
# DX 障害検知時の VPN Failover 確認
aws cloudwatch get-metric-statistics \
--namespace AWS/DX \
--metric-name BGPPeerState \
--dimensions Name=ConnectionId,Value=dxcon-xxxxxxxxxx \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 60 \
--statistics Average
Maximum Resilience (4回線: Location A×2 + Location B×2) は最上位の冗長性だが、コスト面からHigh Resilience (2回線: Location A×1 + Location B×1) を選択するチームも多い。いずれにせよ Single Location だけは絶対に避けること。加えて、DX 回線の物理障害は ISP 側の作業で発生することも多く、VPN Fallback は DX と独立した経路 (異なるCGW/ISP) で整備する必要がある。
6-4. VPC Peering CIDR重複 — グローバル一意性未確保による Peering 不能
症状
- VPC Peering Requestを発行すると「InvalidVpc.Range」または「CIDR overlap」エラーが発生する
- 既存のPeering接続は正常だが、新規VPCとのPeering追加時に必ず失敗する
- マルチアカウント環境で、別アカウントのVPCが同一CIDRレンジを使用していた
原因
各チームや各アカウントがVPCを独立して設計した結果、同じCIDRブロック(例: 10.0.0.0/16)が複数のVPCで使われているケースが多い。
単一アカウント内では問題が顕在化しないため、Peering接続が必要になって初めて重複が発覚する。
解決策: AWS IPAM (IP Address Manager) によるCIDR一元管理
# IPAM の有効化
resource "aws_vpc_ipam" "main" {
description = "Organization-wide IPAM"
operating_regions {
region_name = "ap-northeast-1"
}
}
# Organization全体用プール (RFC1918 10.0.0.0/8 空間)
resource "aws_vpc_ipam_pool" "root" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.main.private_default_scope_id
description = "Root pool — 10.0.0.0/8"
}
resource "aws_vpc_ipam_pool_cidr" "root" {
ipam_pool_id = aws_vpc_ipam_pool.root.id
cidr= "10.0.0.0/8"
}
# Prod 環境専用サブプール (/12 = 10.0.0.0 〜 10.15.255.255)
resource "aws_vpc_ipam_pool" "prod" {
address_family= "ipv4"
ipam_scope_id = aws_vpc_ipam.main.private_default_scope_id
source_ipam_pool_id = aws_vpc_ipam_pool.root.id
description= "Prod environment pool"
}
# IPAM から自動割当を受ける VPC
resource "aws_vpc" "prod_app" {
ipv4_ipam_pool_id= aws_vpc_ipam_pool.prod.id
ipv4_netmask_length = 24 # /24 を自動払い出し
}
IPAM を導入しても、既存 VPC の CIDR を後から変更することはできない。既存 VPC との重複は Peering を諦めて Transit Gateway + CIDR 変換 (NAT層) で回避するか、VPC を再作成する以外に解決策がない。IPAM は新規 VPC 作成時から強制適用するガードレール(SCP で手動 CIDR 設定を禁止)と組み合わせて初めて効果を発揮する。
6-5. Site-to-Site VPN Tunnel Flap — BGP 未設定によるフェールオーバー遅延
症状
- VPN Tunnel の片系障害発生後、もう一方の Tunnel への切り替えに数分〜10分以上かかる
- Static Route 構成のため、障害 Tunnel を経由するパケットがブラックホール化する
- 手動でルートテーブルを書き換えないと通信が復旧しない
原因
Site-to-Site VPN をStatic Route構成で運用しているケースでは、Tunnel 障害を検知する仕組みが存在しない。
Dead Peer Detection (DPD) がTunnel断を検知するまでのタイムアウト(デフォルト30秒)に加え、Static Routeの切り替えが自動化されていないため、手動介入が必要になる。
解決策: BGP有効化 + BFD (Bidirectional Forwarding Detection) 設定
# BGP 有効で Customer Gateway を作成
aws ec2 create-customer-gateway \
--type ipsec.1 \
--bgp-asn 65000 \
--ip-address 203.0.113.1 \
--tag-specifications 'ResourceType=customer-gateway,Tags=[{Key=Name,Value=cgw-onprem}]'
# BGP 動的ルーティングで VPN Connection を作成
aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id cgw-xxxxxxxxxx \
--vpn-gateway-id vgw-xxxxxxxxxx \
--options '{"StaticRoutesOnly":false,"EnableAcceleration":false}'
# BFD 対応の VPN Connection (Terraform)
resource "aws_vpn_connection" "main" {
vpn_gateway_id= aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.onprem.id
type = "ipsec.1"
static_routes_only = false # BGP 有効
# Tunnel 設定: BFD は VPN Configuration XML の outside_ip_address 側で CGW が設定
tunnel1_ike_versions = ["ikev2"]
tunnel1_phase1_dh_group_numbers = [20, 19, 14]
tunnel1_phase2_dh_group_numbers = [20, 19]
tunnel1_startup_action = "start"
tunnel2_ike_versions = ["ikev2"]
tunnel2_startup_action = "start"
}
BGP を有効化しても、CGW(オンプレルータ)側で BFD を設定しないと障害検知速度は改善しない。BGP のデフォルト Hold Time は 90 秒 — BFD なしでは障害から復旧まで最長 90 秒のサービス断が発生する。BFD 設定後は Hold Time を 30 秒以下(BFD 検知: 300ms × 3 = 900ms)まで短縮できる。CGW ベンダー(Cisco/Juniper/Palo Alto 等)ごとに BFD 設定構文が異なる点にも注意。
6-6. TGW Quota 超過 — Attachment 数上限到達による新規 VPC 接続不能
症状
- 新規VPCをTransit GatewayにAttachしようとすると「TransitGatewayAttachmentLimitExceeded」エラー
- Service Quotasコンソールで確認すると「Attachments per Transit Gateway」が上限に達している
- エラーはTGW拡張の直前まで警告なしに発生する
原因
TransitGatewayのAttachment数上限(デフォルト5,000)は大規模組織では到達し得る値だが、CloudWatchのデフォルトメトリクスにはAttachment数の監視項目がない。
組織成長に伴ってVPCが増加し続けるが、Quota監視がないためCapacity不足に気付けない。
解決策: CloudWatch メトリクス + AWS Quota Monitor によるアラート整備
# Quota Monitor (AWS Solutions) の CloudFormation スタック
resource "aws_cloudformation_stack" "quota_monitor" {
name = "quota-monitor"
template_url = "https://solutions-reference.s3.amazonaws.com/quota-monitor-for-aws/latest/quota-monitor-hub.template"
capabilities = ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
parameters = {
MonitoringAccountId = data.aws_caller_identity.current.account_id
SlackWebhook = var.slack_webhook_url
}
}
# TGW Attachment 数を手動確認
aws ec2 describe-transit-gateway-attachments \
--filters "Name=transit-gateway-id,Values=tgw-xxxxxxxxxx" \
"Name=state,Values=available" \
--query "length(TransitGatewayAttachments)" \
--output text
# Quota 上限の確認
aws service-quotas get-service-quota \
--service-code ec2 \
--quota-code L-A2478D36 # Attachments per Transit Gateway
# Quota 引き上げ申請
aws service-quotas request-service-quota-increase \
--service-code ec2 \
--quota-code L-A2478D36 \
--desired-value 10000
Quota 引き上げ申請は AWS サポートによる承認が必要で、数日かかる場合がある。「Attachment が詰まってから申請」では間に合わない。上限の 80% 到達でアラームを発火させ、余裕を持った申請を自動化すること。また、VPN Attachment / Direct Connect Attachment / Peering Attachment も同じ Quota を消費する点を見落としがちなため、全 Attachment 種別を合算して監視する。
6-7. Network Manager 未活用 — Route 分析・変更影響把握不能
症状
- TGW Route Table を変更したあと、影響を受けるVPCやワークロードが事前に把握できない
- 変更後に意図しない通信断が発生し、原因調査に長時間を要する
- マルチアカウント・マルチリージョンにまたがるネットワークトポロジーを俯瞰する手段がない
原因
Network ManagerのGlobal NetworkおよびRoute Analyzerを設定していないため、ネットワーク変更の影響範囲を分析できない状態で作業を行っている。
運用チームが個別VPCのRoute Tableを手動確認するしかなく、見落としが発生する。
解決策: Global Network 構築 + Route Analyzer による変更前影響分析
# Network Manager Global Network の作成
resource "aws_networkmanager_global_network" "main" {
description = "Multi-account production network"
tags = { Name = "global-network-prod" }
}
# Transit Gateway を Global Network に登録
resource "aws_networkmanager_transit_gateway_registration" "main" {
global_network_id= aws_networkmanager_global_network.main.id
transit_gateway_arn = aws_ec2_transit_gateway.main.arn
}
# Route Analyzer でパス検索 — 変更前に疎通確認
aws networkmanager start-route-analysis \
--global-network-id global-network-xxxxxxxxxx \
--source '{"TransitGatewayAttachmentArn":"arn:aws:ec2:ap-northeast-1:111122223333:transit-gateway-attachment/tgw-attach-prod"}' \
--destination '{"TransitGatewayAttachmentArn":"arn:aws:ec2:ap-northeast-1:444455556666:transit-gateway-attachment/tgw-attach-dev"}' \
--include-return-path
# Route Analyzer 結果取得
aws networkmanager get-route-analysis \
--global-network-id global-network-xxxxxxxxxx \
--route-analysis-id <analysis-id>
# Network Manager イベント確認 (変更追跡)
aws networkmanager get-network-resource-relationships \
--global-network-id global-network-xxxxxxxxxx \
--resource-type TRANSIT-GATEWAY-ROUTE-TABLE
Route Analyzer は「現在の設定でパスが通るか」を検証するツールであり、「変更後のパスが通るか」を事前シミュレーションする機能ではない。変更前に Route Analyzer で現状を記録し、変更後に再度実行して差分を比較するワークフローを確立すること。また、Network Manager の Event Stream を有効化しておくと、TGW Route の変更が自動的に CloudWatch Logs に記録され、変更履歴の追跡が可能になる。
- TGW Route Table 単一化 → 環境別RT分離 +
default_route_table_association = "disable"で新規Attachment自動配置を禁止 - PrivateLink 許可リスト破綻 →
aws:PrincipalOrgPaths条件キーでOU単位一括許可 +acceptance_required = false - DX Single Location 断 → High/Maximum Resilience 2〜4回線構成 + Site-to-Site VPN 独立経路でFallback
- VPC Peering CIDR重複 → IPAM強制 + SCP で手動CIDR設定禁止 (既存重複はTGW+NAT層で回避)
- VPN Tunnel Flap → BGP有効化 + CGW側BFD設定でHold Timeを30秒以下へ短縮
- TGW Quota超過 → Quota Monitor導入 + 80%到達でアラーム + 申請は余裕を持って実施
- Network Manager未活用 → Global Network登録 + Route Analyzerで変更前後の疎通を記録・比較
7. アンチパターン→正解パターン変換演習
- 失敗から逆算する設計力: 正解パターンだけを学ぶより、障害事例とセットで把握することで新規設計時の判断速度が上がる。「なぜそうしてはいけないか」が体感できれば、本番環境での再現を防げる
- チーム教育への転用: 変換演習フォーマット (アンチパターン/症状/正解パターン/解説) は設計レビューやオンボーディング資料としてそのまま活用できる
- 段階的移行の設計: 正解パターンへの移行にはダウンタイムが伴う場合がある。症状と影響を把握していれば、移行タイミングと手順を現実的にプランニングできる
下表に7件のアンチパターンと正解パターンを概観する。各演習の移行手順と Terraform 実装は後続のセクションで詳説する。
| # | アンチパターン | 代表的症状 | 正解パターン |
|---|---|---|---|
| 1 | TGW Default Route Table 全利用 | Dev→Prod 経路が全開通、環境間侵害リスク | 環境別 Route Table + Propagation 制御 |
| 2 | PrivateLink Acceptance Required 無効 | 想定外アカウントから接続可能 | Allowed Principals (OU ARN) 自動化 |
| 3 | DX Single Location 1 回線 | DC 障害で全拠点が疎通断 | Multi-Location 2 回線 + VPN Failover |
| 4 | VPC Peering Mesh 構成 | ペア数爆発、推移的ルーティング不可 | TGW Hub-and-Spoke 移行 |
| 5 | Site-to-Site VPN Static Route | 経路変更で手動作業・切替遅延 | BGP 動的経路 + BFD 設定 |
| 6 | CIDR 重複を後付け対応 | IP 枯渇・重複でサービス拡張不能 | IPAM 導入で CIDR 一元管理 (設計初期必須) |
| 7 | クロスアカウント PrivateLink 手動管理 | 承認漏れ・夜間障害時の対応不能 | Organizations OU 連携 + RAM 自動化 |
演習1: TGW Default Route Table 全利用 → 環境別 Route Table 分離
問題: TGW デプロイ後に全 VPC を Default Route Table に集約すると、Prod/Stg/Dev 間の経路が全開通する。Dev 環境が侵害された際に Prod への経路が残るため、セキュリティリスクが極めて高い。セキュリティ監査では最初に指摘される設計ミスの筆頭となる。
移行手順 (Terraform):
resource "aws_ec2_transit_gateway_route_table" "prod" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags= { Name = "tgw-rt-prod", Env = "prod" }
}
resource "aws_ec2_transit_gateway_route_table" "dev" {
transit_gateway_id = aws_ec2_transit_gateway.main.id
tags= { Name = "tgw-rt-dev", Env = "dev" }
}
resource "aws_ec2_transit_gateway_route_table_association" "prod_vpc" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.prod.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
resource "aws_ec2_transit_gateway_route_table_propagation" "shared_to_prod" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.shared.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.prod.id
}
Trade-off: Route Table 数 × Propagation 設定数が増加するため、Terraform モジュール分割と命名規則を事前に整備する。移行時は既存 Static Route を全棚卸しした上で Propagation に置き換えること。
演習2: PrivateLink Acceptance Required 無効 → Allowed Principals + Organizations 連携
問題: acceptance_required = false 設定では VPC Endpoint ID を知っていれば誰でも接続できる。マルチアカウント構成で意図しない外部アカウントからの接続が発生し、機密サービスが意図せず公開状態になるリスクがある。AWS Config の管理下では「非準拠」として継続的にアラートが上がり続ける。
移行手順 (Terraform):
resource "aws_vpc_endpoint_service" "app" {
acceptance_required = true
network_load_balancer_arns = [aws_lb.internal.arn]
}
resource "aws_vpc_endpoint_service_allowed_principal" "org_unit" {
vpc_endpoint_service_id = aws_vpc_endpoint_service.app.id
# Organizations OU ARN を指定することで OU 内アカウントを自動許可
principal_arn = "arn:aws:organizations::123456789012:ou/o-exampleorgid/ou-examp-abcdef"
}
Trade-off: Allowed Principals に OU ARN を指定すると OU 新規追加アカウントが自動許可される。Organizations OU 管理の SCP と組み合わせてアカウント追加フローを制御することが前提となる。
演習3: DX Single Location 1 回線 → Multi-Location 2 回線 + VPN Failover
問題: Direct Connect を単一ロケーション・1 回線で構成すると、DC 設備障害・メンテナンス・ファイバー切断で全拠点が疎通断になる。事業継続性に直結するため、Network アーキテクチャ上で最も危険な単一障害点となる。障害発生後の VPN 手動切替まで RTO が数時間に達することも珍しくない。
移行手順 (Terraform):
resource "aws_dx_connection" "primary" {
name= "dx-primary-tokyo"
bandwidth = "10Gbps"
location = "EqTY2"
tags= { Name = "dx-primary", Priority = "1" }
}
resource "aws_dx_connection" "secondary" {
name= "dx-secondary-osaka"
bandwidth = "10Gbps"
location = "EqOS1"
tags= { Name = "dx-secondary", Priority = "2" }
}
resource "aws_vpn_connection" "failover" {
vpn_gateway_id = aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.main.id
type = "ipsec.1"
static_routes_only= false
tunnel1_ike_versions = ["ikev2"]
tunnel2_ike_versions = ["ikev2"]
}
Trade-off: 2 ロケーション 2 回線は月額コストが最大 4 倍になる。Osaka 側を 1Gbps に絞り、Tokyo DX をメインとし、障害時のみ VPN へ Failover させる 2 段構えが現実解。
演習4: VPC Peering Mesh 構成 → TGW Hub-and-Spoke 移行
問題: 10 VPC を全メッシュ接続すると 45 ペアのピアリング接続が必要になる。各 VPC のルートテーブルに 9 件の経路を追加する管理コストと、VPC Peering の推移的ルーティング非対応の制約が設計を複雑化する。VPC 追加のたびに全既存 VPC のルートテーブル更新が発生し、Limit (125 ペア) への到達も現実的な脅威となる。
移行手順 (Terraform):
resource "aws_ec2_transit_gateway" "hub" {
amazon_side_asn = 64512
auto_accept_shared_attachments = "disable"
default_route_table_association = "disable"
default_route_table_propagation = "disable"
description= "Hub TGW replacing VPC Peering mesh"
}
resource "aws_ec2_transit_gateway_vpc_attachment" "spokes" {
for_each = var.spoke_vpcs
subnet_ids= each.value.private_subnet_ids
transit_gateway_id = aws_ec2_transit_gateway.hub.id
vpc_id = each.value.id
tags = { Name = "tgw-spoke-${each.key}" }
}
Trade-off: TGW は GB あたりのデータ処理料金が発生する (同一 AZ の VPC Peering は無料)。月間 GB 転送量と管理工数を比較して移行判断する。10VPC 以上では管理工数の観点から通常 TGW が優位。
演習5: Site-to-Site VPN Static Route → BGP 動的経路 + BFD 設定
問題: Static Route で VPN を運用すると、オンプレ側の経路変更のたびに AWS コンソールで手動追加が必要になる。フェイルオーバー検知も BGP より遅延し、Tunnel Down 後の RTO が SLA を超えるリスクがある。運用台帳とコンソール設定の乖離によるヒューマンエラーも多発しやすい。
移行手順 (Terraform):
resource "aws_customer_gateway" "bgp" {
bgp_asn = 65000
ip_address = var.customer_gateway_ip
type = "ipsec.1"
tags = { Name = "cgw-bgp" }
}
resource "aws_vpn_connection" "bgp_enabled" {
vpn_gateway_id= aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.bgp.id
type = "ipsec.1"
static_routes_only = false# BGP 有効化 (Static → Dynamic)
tunnel1_dpd_timeout_action = "restart"
tunnel1_ike_versions = ["ikev2"]
tunnel2_dpd_timeout_action = "restart"
tunnel2_ike_versions = ["ikev2"]
}
Trade-off: BGP 有効化には Customer Gateway 側 (オンプレルータ) の設定変更が必要。ルータベンダーごとに設定手順が異なるため、現地ネットワーク担当との連携と事前テストが必須となる。
演習6: CIDR 重複を後付け対応 → IPAM 導入で CIDR 一元管理
問題: VPC CIDR を場当たり的に割り当てると、アカウント間・リージョン間で CIDR 重複が発生する。重複発生後に IPAM を後入れすると既存 VPC の再番が必要となり、数百台の EC2 IP アドレス変更という大規模作業が生じる。拡張が止まる「CIDR 負債」は組織が成長するほど深刻化する。
移行手順 (Terraform):
resource "aws_vpc_ipam" "org" {
operating_regions {
region_name = "ap-northeast-1"
}
operating_regions {
region_name = "ap-northeast-3"
}
}
resource "aws_vpc_ipam_pool" "prod" {
address_family = "ipv4"
ipam_scope_id = aws_vpc_ipam.org.private_default_scope_id
locale= "ap-northeast-1"
}
resource "aws_vpc_ipam_pool_cidr" "prod_range" {
ipam_pool_id = aws_vpc_ipam_pool.prod.id
cidr= "10.0.0.0/8"
}
resource "aws_vpc" "managed" {
ipv4_ipam_pool_id= aws_vpc_ipam_pool.prod.id
ipv4_netmask_length = 24
}
Trade-off: IPAM は 1 リソース/月あたりのコストが発生する。新規 VPC からのみ IPAM 管理に移行し、既存 VPC は段階的に移行するのが現実解。Organizations と統合することで全アカウントの CIDR 可視化も可能になる。
演習7: クロスアカウント PrivateLink 手動管理 → Organizations OU 連携 + RAM 自動化
問題: クロスアカウントの PrivateLink 接続許可を Slack や Excel で属人管理すると、承認担当不在時の夜間障害対応が困難になる。新しいアカウントが追加されるたびに許可申請フローが発生し、運用コストが線形増加する。マルチアカウント規模が拡大するほど手動管理の限界が顕在化する。
移行手順 (Terraform):
resource "aws_ram_resource_share" "privatelink" {
name = "privatelink-cross-account"
allow_external_principals = false
tags = { ManagedBy = "terraform" }
}
resource "aws_ram_principal_association" "org" {
principal = data.aws_organizations_organization.main.arn
resource_share_arn = aws_ram_resource_share.privatelink.arn
}
resource "aws_ram_resource_association" "endpoint_service" {
resource_arn = aws_vpc_endpoint_service.app.arn
resource_share_arn = aws_ram_resource_share.privatelink.arn
}
Trade-off: RAM + Organizations 連携は OU 単位での一括共有のため、Organizations OU 設計の整合性が前提となる。OU 構造が未整備の場合は先に OU 設計を完了させてから本設定に移行する。
8. まとめ — マルチアカウント網本番運用への道と次のステップ
本記事では TGW・PrivateLink・Direct Connect・VPC Peering・Site-to-Site VPN の 5 本柱を統合的に扱い、マルチアカウント網の本番運用設計を一気通貫で習得した。§7 の変換演習で「アンチパターン → 正解パターン」の思考回路を身につけ、実際の設計レビューとオンボーディング教材として活用してほしい。Network Vol1 (VPC 基礎) → Hybrid 専門編 → 本 Vol2 の三部作を通じて、AWS Network 運用の全体像が完成する。
8-1 本記事で学んだこと
- TGW 5 Route Table 分離設計: Default Route Table に全 VPC を集約せず、Prod/Stg/Dev/Shared/Egress の 5 系統に分離し Propagation で経路を精密制御する本番運用基本形を習得した
- PrivateLink 3 形態の使い分け: Interface/Gateway/Endpoint Service を用途・コスト・管理コストで選択し、Organizations OU ARN による自動スケール接続制御の実装方法を習得した
- DX Maximum Resilience 構成: Multi-Location 2 回線 + VPN 自動 Failover による DX Gateway 冗長設計と、BGP Community Tagging によるコスト最適化ルーティングを習得した
- VPC Peering vs TGW 定量判断: 接続数・帯域・コスト・管理工数の 4 軸で接続方式を定量判断するフレームワークと、Mesh → Hub-Spoke 移行ロードマップを習得した
- BGP 本番運用: Static Route → BGP 移行による動的経路制御、BFD デッドタイマーによる高速切替、Accelerated VPN による性能最適化を習得した
- IPAM + Organizations CIDR 一元管理: 設計初期からの IPAM 導入によるマルチアカウント・マルチリージョン CIDR 統合管理で後付け再番を防ぐ設計原則を習得した
- 5 本柱統合本番設計: TGW + PrivateLink + DX + VPC Peering + Site-to-Site VPN の 5 本柱を統合し、マルチアカウント網の本番運用グレード設計を一気通貫で理解した
8-2 落とし穴10選
マルチアカウント網本番運用で実際に観測される落とし穴を10件列挙する。設計レビューチェックリストとして活用されたい。
- TGW Route Table を Default 1 枚で運用: 環境間が全開通しセキュリティレビューで必ず指摘される。デプロイ初日から環境別 Route Table を設計すること
- PrivateLink Acceptance Required 無効のまま本番適用: 意図しないアカウントからの接続を許す。必ず
acceptance_required = true+ Allowed Principals の組み合わせで設計する - DX 1 回線運用でコスト削減: DC 障害・メンテナンス・ファイバー切断で全拠点が疎通断になる。VPN Failover の事前設定が最低ラインのリスク対策
- VPC Peering の推移的ルーティング前提で設計: A→B→C の中継はできない。Shared Services 経由のトラフィック集約には TGW を使う
- Static Route で大規模 VPN 運用: オンプレ経路変更のたびに全 Static Route を手動更新するリスクが生じる。BGP 有効化を最初から計画する
- CIDR 設計を後回し: 重複 CIDR が発生してから IPAM を後入れすると、VPC の再番という大規模作業が必要になる。CIDR 設計は Organizations 構築と同時に実施する
- TGW Cross-Region Peering のレイテンシ未測定: リージョン間レイテンシを事前測定せずにマルチリージョン構成を組むと、アプリケーション性能 SLA を満たせない
- PrivateLink の Private DNS 名前解決を未設定: DNS 名でサービスを呼び出せず、IP ハードコードという管理困難な状態に陥る。VPC Endpoint の
private_dns_enabled = trueを忘れずに設定する - BGP Community Tagging なしの DX 本番運用: オンプレ側でのトラフィック分散・優先制御ができない。Community 設計は DX 開通と同時に合意する
- VPC Peering 追加時のセキュリティグループ更新漏れ: ルートテーブルを更新しても、セキュリティグループで許可していなければ疎通しない。Peering 追加チェックリストに SG 更新を必ず含める
- Vol1 VPC 基礎編: VPC 基礎 — TGW × VPC Lattice × PrivateLink 統合実装入門
単体 VPC 設計・TGW 基礎・Lattice サービスディスカバリ・PrivateLink 基礎を学ぶ出発点 - Hybrid 専門編: Hybrid 専門編 — Direct Connect × VPN × TGW 詳細設計
DX 物理回線設計・VPN 詳細・TGW Cross-Region 連携に特化した深掘り編 - Vol2 マルチアカウント網編 (本記事): TGW × PrivateLink × DX × VPC Peering × VPN を統合した 5 本柱の本番運用設計
Network Vol1 VPC 基礎編 — TGW × Lattice × PrivateLink 入門へ
8-3 全クロスリンク — AWS 本番運用シリーズ完全ナビ
- IAM: Vol1 IAM ポリシー設計 — 最小権限・SCP・Permission Boundary
マルチアカウント網の権限設計はこちらで基礎固め - EKS: Vol1 EKS クラスタ設計 — IRSA × ALB Ingress × Karpenter
VPC 内 EKS ノードの Network 連携設計と組み合わせて活用 - 復旧運用: Incident Response Runbook — 事後レビュー・Automation 自動復旧
DX/VPN 障害時の復旧自動化フローと組み合わせて活用 - AI Bedrock: Vol1 Bedrock Agents — プロダクション基礎
PrivateLink 経由の Bedrock 接続設計はこちらを参照 - セキュリティ: Vol1 セキュリティ運用 — Detective Controls × Compliance
TGW Route Table 分離設計とセキュリティ監査要件を組み合わせて読む - コスト最適化: Vol1 Cost Optimization — Reserved/Savings Plans × Compute Optimizer
DX 帯域・TGW データ処理料金のコスト最適化フレームワーク - マルチアカウント: Vol1 Multi-Account — Organizations × Control Tower × Landing Zone
本記事の RAM/Organizations 連携の前提となる OU 設計はこちら - Observability: Vol1 Observability — Application Signals × X-Ray × CloudWatch
TGW/DX の CloudWatch メトリクス監視設計と合わせて活用 - Network VPC 基礎: Vol1 VPC 基礎 — TGW × Lattice × PrivateLink 入門
本記事 Vol2 の前提知識。単体 VPC 設計から学ぶ出発点 - Network Hybrid 専門編: Hybrid 専門編 — DX × VPN × TGW 詳細設計
DX 物理回線設計・VPN 詳細を深掘りする補完編 - Network Vol2 (本記事): マルチアカウント網 — TGW × PrivateLink × DX × Peering × VPN 統合本番運用
- DevOps: Vol1 DevOps — CodePipeline × CodeBuild × GitHub Actions
Network インフラの Terraform CI/CD パイプライン設計と組み合わせて活用 - Database Vol1: Vol1 RDS × Aurora × DynamoDB 本番設計
マルチ AZ DB を収容する VPC サブネット設計はこちらを参照 - Database Vol2: Vol2 DMS × Aurora Global × Streams × Backup
クロスリージョン Aurora Global は TGW Cross-Region と組み合わせて設計 - Database Vol3: Vol3 ElastiCache × DAX × MemoryDB
低レイテンシ DB のサブネット配置と PrivateLink 接続設計を参照 - Serverless Vol1: Vol1 Lambda × API GW × Step Functions
VPC 内 Lambda の ENI 設計と TGW との接続パターンを参照 - Serverless Vol2: Vol2 EventBridge × SQS × SNS × Kinesis
VPC Endpoint 経由のメッセージングサービス接続はこちらを参照 - Container Vol1: Vol1 ECS × Fargate × ECR 本番運用
Fargate タスクの VPC ネットワーク・PrivateLink ECR 接続設計を参照 - Container Vol2: Vol2 EKS × GitOps — ArgoCD × Kustomize × Argo Rollouts
EKS クラスタのマルチアカウント VPC 設計と TGW 接続を参照 - Storage: Vol1 S3 × EFS × FSx × Storage Gateway
S3 Gateway Endpoint / EFS Interface Endpoint の VPC 設計はこちら - Edge/CDN: Vol1 CloudFront × Lambda@Edge × Route53 高速化
オンプレ→CloudFront→PrivateLink のハイブリッド CDN 設計と組み合わせて活用 - Analytics: Vol1 Glue × Athena × Redshift — データレイク本番構築
VPC 内 Redshift への PrivateLink アクセスと IPAM CIDR 設計を参照 - ML/AI Vol2: Vol2 Bedrock Embedding × RAG × Knowledge Bases × Agents
VPC PrivateLink 経由の Bedrock 本番接続設計は本記事と組み合わせて読む
8-4 Network Vol3 予告 — Service Mesh・Cloud WAN・Multi-Region Active-Active 網
Network 本番運用シリーズは Vol3 で完結する予定。本記事 (Vol2) で習得したマルチアカウント網の基盤を前提に、以下のテーマを深掘りする。
| テーマ | 概要 | Vol2 との連携軸 |
|---|---|---|
| VPC Lattice Service Mesh | サービスディスカバリ・認証・レート制限を L7 で一元管理 | TGW Attachment と Lattice の使い分け判断を深掘り |
| AWS Cloud WAN | グローバル SD-WAN をマネージドで構築し Core Network Policy で経路制御 | TGW Cross-Region Peering の上位互換として位置づけ |
| Multi-Region Active-Active 網 | 東京・大阪 Active-Active 構成の Route53 × DX Gateway × TGW 設計 | DX Multi-Location 冗長構成の応用形として展開 |
| Network Manager | TGW 網全体を可視化・トポロジー管理・イベント検知 | Vol2 で構築したマルチ TGW の全体監視レイヤー |
AWS Network 運用三本柱 (VPC 基礎 Vol1 + Hybrid 専門編 + マルチアカウント網 Vol2) の習得を土台に、Vol3 で Service Mesh と Cloud WAN を加えることで、エンタープライズグレードの Network 設計力が完成する。まずは本記事の 5 本柱統合設計を実環境で試し、フィードバックを積み重ねてほしい。
8-5 Network Vol2 設計完遂チェックリスト
本記事で習得した設計パターンが実装済かどうかを確認するためのチェックリスト。新規 AWS 環境構築時および既存環境の棚卸し時に活用されたい。
TGW 設計
– [ ] 環境別 Route Table (Prod/Stg/Dev/Shared/Egress) を分離設定済
– [ ] Propagation と Static Route を目的別に使い分けている
– [ ] Route Table 変更時の影響範囲を Terraform plan で事前確認する手順がある
– [ ] TGW Cross-Region Peering のレイテンシを事前測定済
PrivateLink 設計
– [ ] acceptance_required = true + Allowed Principals (OU ARN) で自動スケール制御済
– [ ] Private DNS 名前解決の設定を全 Interface Endpoint で確認済
– [ ] クロスアカウント接続は RAM + Organizations 連携で自動化済
Direct Connect 設計
– [ ] Multi-Location 2 回線または VPN Failover を設定済
– [ ] BGP Community Tagging でオンプレ側トラフィック分散ポリシーを合意済
– [ ] DX 障害時の VPN 自動 Failover を動作確認済
VPC Peering / VPN 設計
– [ ] VPC 数が 10 以上の場合は TGW Hub-and-Spoke に移行済
– [ ] Site-to-Site VPN は BGP 有効化済 (Static Route 運用の脱却)
– [ ] Peering 追加時のセキュリティグループ更新チェックリストが運用手順書にある
CIDR / IPAM 設計
– [ ] 新規 VPC は IPAM Pool から割り当てる運用フローが確立済
– [ ] 全アカウント・全リージョンの CIDR 割り当て状況が IPAM で可視化済