VPC ピアリング接続
ユースケース: アカウント A の ECS タスクが、アカウント B のRDS データベースにプライベートネットワーク経由で接続する必要があります — パブリックインターネットは関与しません。
🧩 問題
2 つの AWS アカウントに別々の VPC があります:
| リソース | アカウント | VPC CIDR(例) |
| ECS クラスター(Fargate/EC2) | アカウント A — 111111111111 | 10.0.0.0/16 |
| RDS データベース(PostgreSQL/MySQL) | アカウント B — 222222222222 | 10.1.0.0/16 |
デフォルトでは、これら 2 つの VPC は完全に隔離されています。ECS タスクは、別のアカウント内の RDS エンドポイントを解決または到達できません。プライベートネットワークブリッジを作成するため、VPC ピアリング接続が必要です。
🔑 VPC ピアリングとは
VPC ピアリング接続は、2 つの VPC 間の1 対 1 のネットワークリンクで、プライベート IP アドレスを使用してトラフィックをルーティングします。いずれかの VPC のリソースは、同じネットワーク内にあるかのように通信します。
主な特性:
-
アカウント間およびリージョン間で機能します(リージョン間ピアリング)
-
トラフィックは AWS バックボーン上に留まります — パブリックインターネットを通過することはありません
-
リージョン間トラフィックは自動的に暗号化されます
-
単一障害点また は帯域幅ボトルネックはありません
-
ピアリング接続を作成するための料金はありません(標準データ転送料金が適用されます)
-
同じアベイラビリティゾーン内のデータ転送は無料です。アカウント間でも同様です
重要な制約: 2 つの VPC はCIDR ブロックが重複していない必要があります。10.0.0.0/16 と 10.0.0.0/16 が重複している場合、VPC ピアリングは機能しません。AWS PrivateLink を使用するか、いずれかの VPC を再度アドレス指定する必要があります。
🏗️ アーキテクチャの概要
┌──────────────────────────────────────────────────────────────────────────┐
│ VPC ピアリング接続 │
│ (pcx-0abc123...) │
│ │
│ アカウント A (111111111111) アカウント B (222222222222) │
│ VPC: 10.0.0.0/16 VPC: 10.1.0.0/16 │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ プライベートサブネット │ │ プライベートサブネット │ │
│ │ │ │ │ │
│ │ ┌───────────────┐ │ │ ┌───────────────┐ │ │
│ │ │ ECS タスク │ │◄────────►│ │ RDS インスタンス│ │ │
│ │ │ (Fargate) │ │ プライベ │ │ (PostgreSQL) │ │ │
│ │ └───────────────┘ │ ートトラ │ └───────────────┘ │ │
│ │ │ フィック │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ ルートテーブル: ルートテーブル: │
│ 10.1.0.0/16 → pcx-0abc123 10.0.0.0/16 → pcx-0abc123 │
│ │
│ セキュリティグループ: セキュリティグループ: │
│ アウトバウンド → 10.1.0.0/16:5432 インバウンド ← 10.0.0.0/16:5432 │
└──────────────────────────────────────────────────────────────────────────┘
📋 前提条件チェックリスト
開始する前に、以下を確認してください:
-
両方の AWS アカウント(VPC、EC2、RDS、IAM)で管理者または十分な IAM 権限がある
-
2 つの VPC の CIDR ブロックが重複していない
-
両方のアカウントの VPC ID を知っている
-
ピアアカウントのアカウント ID を知っている
-
RDS インスタンスがプライベートサブネット内にある(パブリックアクセシビリティは不要)
-
両方の VPC で DNS ホスト名と DNS 解決が有効になっている
🚀 ステップバイステップセットアップ
ステップ 1 — VPC ピアリング接続を作成する(アカウント A — リクエスター)
-
VPC コンソール → ピアリング接続 → ピアリング接続の作成を開く
-
詳細を入力します:
- 名前:
ecs-to-rds-cross-account-peer - VPC ID(リクエスター): ECS クラスターが実行される VPC を選択
- アカウント: 別のアカウントを選択 → アカウント B の ID(
222222222222)を入力 - リージョン: このリージョン(同じリージョン)または別のリージョン(クロスリージョンの場合)を選択
- VPC ID(アクセプター): RDS がホストされているアカウント B の VPC ID を入力
- 名前:
-
ピアリング接続を作成をクリック 接続ステータスは受け入れ待機中と表示されます。
AWS CLI の同等コマンド:
aws ec2 create-vpc-peering-connection \
--vpc-id vpc-0aaa1111aaaa1111a \
--peer-vpc-id vpc-0bbb2222bbbb2222b \
--peer-owner-id 222222222222 \
--peer-region us-east-1 \
--tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=ecs-to-rds-cross-account-peer}]'
ステップ 2 — ピアリング接続を受け入れる(アカウント B — アクセプター)
-
アカウント B にログイン
-
VPC コンソール → ピアリング接続を開く
-
アカウント A からの保留中のピアリング要求を見つける
-
それを選択 → アクション → リクエストを受け入れる
-
受け入れを確認 ステータスはアクティブに変わるはずです。
AWS CLI の同等コマンド:
aws ec2 accept-vpc-peering-connection \
--vpc-peering-connection-id pcx-0abc123def456ghi7
ステップ 3 — ルートテーブルを更新する(両方のアカウント)
これは、人々が最も頻繁に見落とすステップです。両方の VPC は、ピアリング接続を通じてピア VPC の CIDR をポイントするルートが必要です。
アカウント A — ECS VPC ルートテーブル
ECS タスクが実行されるサブネットにルートを追加します:
| 宛先 | ターゲット |
10.1.0.0/16(アカウント B の VPC CIDR) | pcx-0abc123def456ghi7(ピアリング接続) |
重要: ECS タスクが起動される可能性があるすべてのサブネット用にルートテーブルを更新してください。Fargate を使用している場合は、ECS サービスの networkConfiguration で指定されたサブネット用にルートテーブルを更新してください。
aws ec2 create-route \
--route-table-id rtb-0aaa1111 \
--destination-cidr-block 10.1.0.0/16 \
--vpc-peering-connection-id pcx-0abc123def456ghi7
アカウント B — RDS VPC ルートテーブル
RDS が配置されているサブネットにルートを追加します:
| 宛先 | ターゲット |
10.0.0.0/16(アカウント A の VPC CIDR) | pcx-0abc123def456ghi7(ピアリング接続) |
RDS サブネットグループ内のすべてのサブネットに関連付けられたルートテーブルを更新してください。
aws ec2 create-route \
--route-table-id rtb-0bbb2222 \
--destination-cidr-block 10.0.0.0/16 \
--vpc-peering-connection-id pcx-0abc123def456ghi7
ステップ 4 — セキュリティグループを構成する
アカウント B — RDS セキュリティグループ(インバウンド)
アカウント A の ECS VPC からのデータベースポートのトラフィックを許可します:
| タイプ | プロトコル | ポート | ソース | 説明 |
| カスタム TCP | TCP | 5432(PostgreSQL)または 3306(MySQL) | 10.0.0.0/16 | アカウント A から ECS を許可 |
注: 同じリージョン、同じアカウントのピアリングの場合、セキュリティグループを直接参照できます。クロスアカウントピアリングの場合、CIDR ブロックをソースとして使用する必要があります — セキュリティグループ参照のクロスアカウント参照は、同じリージョン内のピアリング接続でのみサポートされています。
aws ec2 authorize-security-group-ingress \
--group-id sg-0bbb2222rds \
--protocol tcp \
--port 5432 \
--cidr 10.0.0.0/16
アカウント A — ECS タスクセキュリティグループ(アウトバウンド)
ECS タスクセキュリティグループがアウトバウンドトラフィックを制限する場合(デフォルトの 0.0.0.0/0 許可なし)、アウトバウンドルールを追加します:
| タイプ | プロトコル | ポート | 宛先 | 説明 |
| カスタム TCP | TCP | 5432 | 10.1.0.0/16 | アカウント B の RDS へのアウトバウンドを許可 |
ステップ 5 — VPC ピアリングの DNS 解決を有効にする
これは見落としやすい重要なステップです。デフォルトでは、ECS タスクが RDS エンドポイントホスト名(例:mydb.abc123.us-east-1.rds.amazonaws.com)を解決するとき、パブリック IP に解決される場合があります。ピアリング接続で DNS 解決を有効にすると、RDS エンドポイントがピア VPC からプライベート IP に確実に解決されます。
-
アカウント A(リクエスター):VPC コンソール → ピアリング接続 → 接続を選択 → アクション → DNS 設定を編集に移動
- 有効にする:リクエスター DNS 解決 — 「アクセプター VPC がリクエスター VPC ホストの DNS をプライベート IP に解決することを許可」
-
アカウント B(アクセプター):同じステップですが、アクセプター DNS 解決 — 「リクエスター VPC がアクセプター VPC ホストの DNS をプライベート IP に解決することを許可」
両側は、それぞれの設定を独立して有効にする必要があります。
AWS CLI:
# アカウント A から実行
aws ec2 modify-vpc-peering-connection-options \
--vpc-peering-connection-id pcx-0abc123def456ghi7 \
--requester-peering-connection-options AllowDnsResolutionFromRemoteVpc=true
# アカウント B から実行
aws ec2 modify-vpc-peering-connection-options \
--vpc-peering-connection-id pcx-0abc123def456ghi7 \
--accepter-peering-connection-options AllowDnsResolutionFromRemoteVpc=true
また、両方の VPC でこれらの設定が有効になっていることを確認してください:
-
DNS ホスト名を有効化 →
true -
DNS 解決を有効化 →
true
ステップ 6 — ネットワーク ACL を確認する
ネットワーク ACL(NACL)はステートレスで、セキュリティグループの前に評価されます。両方のサブネット上の NACL が以下を許可していることを確認してください:
アカウント A のサブネット(ECS):
-
アウトバウンド: ポート
5432で10.1.0.0/16への TCP を許可 -
インバウンド: エフェメラルポート(
1024-65535)上の10.1.0.0/16からの TCP を許可 — リターントラフィック用
アカウント B のサブネット(RDS):
-
インバウンド: ポート
5432で10.0.0.0/16からの TCP を許可 -
アウトバウンド: エフェメラルポート(
1024-65535)上の10.0.0.0/16への TCP を許可 — リターントラフィック用
デフォルト NACL を使用している場合(すべて許可)、変更は不要です。
ステップ 7 — 接続する ECS タスクを構成する
ECS タスク定義で、RDS エンドポイントを環境変数として渡すか、資格情報用に AWS Secrets Manager を使用します。
タスク定義スニペット(Fargate、awsvpc モード):
{
"containerDefinitions": [
{
"name": "my-app",
"image": "my-app:latest",
"environment": [
{
"name": "DB_HOST",
"value": "mydb.abc123.us-east-1.rds.amazonaws.com"
},
{
"name": "DB_PORT",
"value": "5432"
}
],
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:us-east-1:222222222222:secret:mydb-creds"
}
]
}
],
"networkMode": "awsvpc"
}
クロスアカウント Secrets Manager アクセス用: アカウント B 内のシークレットには、アカウント A の ECS タスク実行ロールがそれを読み取ることを許可するリソースポリシーが必要です。あるいは、アカウント A の Secrets Manager に認証情報のコピーを保存します。
✅ 検証とテスト
アカウント A 内の ECS タスクまたは EC2 からテストする
# DNS 解決チェック — 10.1.x.x 範囲のプライベート IP を返すはず
dig mydb.abc123.us-east-1.rds.amazonaws.com +short
# 接続チェック
telnet mydb.abc123.us-east-1.rds.amazonaws.com 5432
# または nc(netcat)を使用
nc -zv mydb.abc123.us-east-1.rds.amazonaws.com 5432
失敗時に確認すること
| 症状 | 考えられる原因 | 修正 |
| DNS がパブリック IP に解決される | ピアリング接続で DNS 解決が有効になっていない | リクエスター/アクセプター DNS 解決を有効にする(ステップ 5) |
| 接続がタイムアウト | ルートテーブルにルートがない | ピアリング接続経由でピア CIDR へのルートを追加(ステップ 3) |
| 接続が拒否される | セキュリティグループがブロック | RDS SG にアカウント A CIDR のインバウンドルールを追加(ステップ 4) |
| ピアリングが「保留中」を表示 | まだ受け入れられていない | アカウント B で受け入れる(ステップ 2) |
| ピアリングが「失敗」を表示 | CIDR が重複している | 1 つの VPC を再度アドレス指定するか、代わりに PrivateLink を使用 |
| 断続的な失敗 | 一部のサブネットでのみルートテーブルが更新されている | ECS タスクまたは RDS インスタンスが存在するすべてのサブネットを更新(ステップ 3) |
| EC2 からは機能するが ECS からは機能しない | ECS タスクの間違ったセキュリティグループ | awsvpc モードでは、タスクセキュリティグループがアクセスを制御します。インスタンス SG ではなく |
🔄 Terraform の例
# ─── アカウント A(ECS)───
resource "aws_vpc_peering_connection" "ecs_to_rds" {
vpc_id = aws_vpc.ecs_vpc.id
peer_vpc_id = "vpc-0bbb2222bbbb2222b" # アカウント B の VPC ID
peer_owner_id = "222222222222" # アカウント B のアカウント ID
peer_region = "us-east-1"
tags = {
Name = "ecs-to-rds-cross-account"
}
}
# ─── アカウント B(RDS)───
resource "aws_vpc_peering_connection_accepter" "rds_accept" {
provider = aws.account_b
vpc_peering_connection_id = aws_vpc_peering_connection.ecs_to_rds.id
auto_accept = true
}
# ─── DNS 解決(両側)───
resource "aws_vpc_peering_connection_options" "requester_dns" {
vpc_peering_connection_id = aws_vpc_peering_connection.ecs_to_rds.id
requester {
allow_remote_vpc_dns_resolution = true
}
}
resource "aws_vpc_peering_connection_options" "accepter_dns" {
provider = aws.account_b
vpc_peering_connection_id = aws_vpc_peering_connection.ecs_to_rds.id
accepter {
allow_remote_vpc_dns_resolution = true
}
}
# ─── ルートテーブル───
resource "aws_route" "ecs_to_rds_route" {
route_table_id = aws_route_table.ecs_private.id
destination_cidr_block = "10.1.0.0/16"
vpc_peering_connection_id = aws_vpc_peering_connection.ecs_to_rds.id
}
resource "aws_route" "rds_to_ecs_route" {
provider = aws.account_b
route_table_id = aws_route_table.rds_private.id
destination_cidr_block = "10.0.0.0/16"
vpc_peering_connection_id = aws_vpc_peering_connection.ecs_to_rds.id
}
# ─── セキュリティグループ───
resource "aws_security_group_rule" "rds_allow_ecs" {
provider = aws.account_b
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
security_group_id = aws_security_group.rds_sg.id
description = "Allow PostgreSQL from ECS in Account A"
}
⚖️ VPC ピアリング vs. 代替案
| 機能 | VPC ピアリング | AWS PrivateLink + NLB | トランジットゲートウェイ | VPC Lattice |
| 複雑性 | 低 | 中~高 | 中 | 中 |
| コスト | 作成は無料;データ転送料金 | NLB + PrivateLink 時間当たり + データ | TGW 時間当たり + データ | リクエスト単位の価格設定 |
| CIDR の重複 | サポートされていない | サポート | サポートされていない | サポート |
| 露出範囲 | VPC 全体から VPC | 特定のサービスのみ | VPC 全体から VPC | 特定のリソースのみ |
| スケーラビリティ | 1:1 接続(VPC ごと最大 125 個) | エンドポイント単位で複数コンシューマー | ハブアンドスポーク(数千の VPC) | サービスメッシュアプローチ |
| クロスリージョン | サポート | クロスリージョンはピアリングが必要 | サポート(ピアリングを伴う) | サポート |
| 最適用途 | シンプルで低コスト の 1:1 接続 | 粒度の高いアクセス、CIDR の重複 | 大規模組織、多数の VPC | 最新のサービス間メッシュ |
VPC ピアリングを選択する場合: VPC が少数で、CIDR が重複せず、直接接続を求める最もシンプルで安価なオプションが欲しい場合。
VPC ピアリングを選択しない場合: CIDR が重複している、きめ細かいサービスレベルのアクセス制御が必要、または多数の VPC を相互接続する必要がある場合。
⚠️ よくある落とし穴とコツ
-
DNS 解決の忘れ — #1 の問題。ピアリング接続で DNS 解決を有効にしないと、RDS エンドポイントがパブリック IP に解決され、トラフィックはインターネットに送信されます(セキュリティグループによってブロックされます)。常に両側で DNS 解決を有効にしてください。
-
すべてのサブネットでルートテーブルが更新されていない — ECS タスクが複数のサブネットで起動できる場合、関連付けられたすべてのルートテーブルにピアリングルートが必要です。1 つを見落とすと、そのサブネット内のタスクは RDS に到達できません。
-
ECS
awsvpcモードセキュリティグループ —awsvpcネットワークモード(Fargate に必須)では、タスクレベルのセキュリティグループがネットワークアクセスを制御します。EC2 ホストセキュリティグループではありません。タスク SG がアウトバウンドで RDS ポートを許可していることを確認してください。 -
RDS IP は変更後に変わる — アップグレード、リサイズ、またはフェイルオーバー後に RDS インスタンスは IP が変わる可能性があります。常に DNS エンドポイントを使用し、IP をハードコードしないでください。ピアリングで DNS 解決を有効にすれば、エンドポイントは新しいプライベート IP に正しく解決されます。
-
推移的ピアリングはサポートされていない — VPC A が VPC B とピアリングし、VPC B が VPC C とピアリングしている場合、VPC A は VPC B を通じて VPC C に到達できません。各ペアは独自のピアリング接続が必要です(またはトランジットゲートウェイを使用)。
-
クロスアカウントセキュリティグループ参照 — ピア VPC のセキュリティグループをルール内で参照できるのは、同じリージョンのピアリングの場合のみです。クロスリージョンピアリングの場合、CIDR ブロックを使用してください。
-
Secrets Manager クロスアカウントアクセス — DB 認証情報がアカウント B の Secrets Manager に保存されている場合、シークレットのリソースポリシーがアカウント A の ECS タスク実行ロールにアクセスを許可する必要があります。また、CMK を使用している場合は KMS キーポリシーも必要です。
📎 便利な AWS CLI コマンド
# すべてのピアリング接続を一覧表示
aws ec2 describe-vpc-peering-connections
# ピアリング接続ステータスを確認
aws ec2 describe-vpc-peering-connections \
--vpc-peering-connection-ids pcx-0abc123def456ghi7 \
--query 'VpcPeeringConnections[0].Status'
# ルートテーブルを確認
aws ec2 describe-route-tables \
--route-table-ids rtb-0aaa1111 \
--query 'RouteTables[0].Routes'
# セキュリティグループルールを確認
aws ec2 describe-security-groups \
--group-ids sg-0bbb2222rds \
--query 'SecurityGroups[0].IpPermissions'
# ピアリング接続を削除
aws ec2 delete-vpc-peering-connection \
--vpc-peering-connection-id pcx-0abc123def456ghi7
📚 参考資料
最後更新:2026 年 3 月