VPC Peering(VPCピアリング)は、2つのVPCをプライベートIPのまま直接つなぐAWSの機能です。ゲートウェイもVPNも挟まないため構成は単純ですが、接続を作っただけでは1パケットも流れません。承認、両側のルート、セキュリティグループ、必要ならDNS解決オプションまでをそろえて、はじめて通信が成立します。この記事では、AWS CLIとTerraformでそれぞれの作業を再現できる形で示し、同一AZ無料の判定条件、疎通しないときの切り分け、Transit Gatewayへ切り替えるべき境目まで扱います。
まとめ:VPC Peeringを選ぶ条件と設定で必ず踏む4つの作業
VPC Peeringが向くのは、つなぐVPCが少なく、CIDRが重ならず、オンプレミスや共通のインターネット出口を相手VPCと共有する必要がない構成です。1本の接続は2つのVPCの1対1の関係で、推移的な中継はできません。VPCが増えると接続数は掛け算で増えるので、4つを超えそうな段階でTransit Gatewayを検討に入れます。
設定作業は4つに分かれます。①リクエスタ側で接続を作成しアクセプタ側で承認する、②両側のルートテーブルに相手CIDR宛ての経路を足す、③セキュリティグループで相手からの通信を許可する、④プライベートDNS名で呼ぶならDNS解決オプションを両側で有効にする、の順です。料金は接続自体には掛からず、同一AZ内の転送は2021年5月から無料、AZをまたぐ転送とリージョン間転送は通常のデータ転送料金になります。
マルチアカウントのネットワーク全体を設計し直す段階なら、Peeringを足し続ける前に経路設計そのものを見直したほうが結果的に安く済みます。構成の棚卸しから相談したい場合は、AWS・Google Cloud・Azureのインフラ構築支援で対応しています。
VPC Peeringの仕組みと推移不可・CIDR重複不可など実装前に知る制約
リクエスタとアクセプタの承認フローと7日で期限切れになる状態遷移
接続は、リクエスタVPCの所有者が申請し、アクセプタVPCの所有者が承認して有効になります。AWS公式のVPC Peeringの仕組みによると、状態は initiating-request から pending-acceptance を経て provisioning、active へ進みます。承認されないまま放置した申請は7日で expired になり、以後はどちらの側も操作できません。
クロスアカウントで詰まりやすいのがこの待ち時間です。相手企業の担当者に承認を依頼したまま1週間が過ぎ、作り直しになる例は少なくありません。申請前に相手側の承認者と作業日を決めておくと手戻りが減ります。
数の上限も先に確認しておきます。VPC Peeringのクォータでは、1つのVPCあたりのactiveな接続は既定50本で、申請により125本まで引き上げられます。未承認の申請は既定25件が上限です。
推移的ピアリング不可とIGW・NAT・VPNを相手VPCから借りられない制約
VPC AがBとCの両方とつながっていても、BからAを経由してCへは届きません。BとCを通信させたいなら、BとCの間に別の接続を作ります。これが推移的ピアリング非対応の意味です。
同じ理由で、相手VPCのゲートウェイも借りられません。公式ドキュメントでは、相手VPCのインターネットゲートウェイ、NATデバイス、Site-to-Site VPN、Direct Connect、S3向けゲートウェイエンドポイントのいずれも、こちら側のリソースからは使えないと明記されています。「共通VPCにNATを1つ置いて各VPCから相乗りさせる」構成は、Peeringでは成立しません。
CIDRの重複も作成時点で弾かれます。複数のIPv4 CIDRを持つVPCでは、使う予定のないブロックが1つでも重なっていれば接続は作れません。CIDRの切り方に不安がある場合は、CIDRの読み方とAWS VPCでのサブネット設計で先に割り当て表を作っておくと安全です。
同一リージョンとクロスリージョンで変わるMTU・SG参照・DNSの挙動差
同じPeeringでも、同一リージョン内かリージョンをまたぐかで使える機能が変わります。設計段階で差を押さえておかないと、東京と大阪をつないだときにセキュリティグループの書き方から作り直すことになります。
| 項目 | 同一リージョン | クロスリージョン |
|---|---|---|
| MTU上限 | 9001バイト | 8500バイト |
| 相手のSG参照 | 可能 | 不可(CIDRで指定) |
| プライベートDNS解決 | RFC 1918範囲なら既定で可 | DNS解決オプションが必須 |
| 転送料金 | 同一AZ無料・AZ間は有料 | リージョン間転送料金 |
表の値は公式ガイドの制約一覧に基づきます。クロスリージョンでジャンボフレームを前提にしたアプリケーションを動かす場合は、MTU 8500で分割が起きないかを事前に確認してください。
検証環境の構成とAWS CLIでピアリング接続を作成・承認・ルーティングする手順
検証用VPC2つのCIDR設計とDNS属性・IAM権限など作業前の前提条件
ここからの例は、アカウントAのVPC A(10.10.0.0/16)とアカウントBのVPC B(10.20.0.0/16)を、同じ東京リージョン(ap-northeast-1)でつなぐ構成です。同一アカウントなら、アカウントIDの指定を省くだけで同じ手順が使えます。
作業前に確かめるのは、CIDRが重ならないこと、両VPCで enableDnsSupport と enableDnsHostnames が有効なこと、作業ユーザーに ec2:CreateVpcPeeringConnection・ec2:AcceptVpcPeeringConnection・ec2:CreateRoute の権限があることです。DNS属性は aws ec2 describe-vpc-attribute --attribute enableDnsHostnames で確認できます。コマンドはAWS CLI 2.37系(2026年9月時点)で確認できる構文に合わせています。
CLIでピアリング接続を作成しアクセプタ側で承認してactiveにする手順
リクエスタ側で create-vpc-peering-connection を実行し、返ってきた pcx- で始まるIDをアクセプタ側へ渡します。
# アカウントA(リクエスタ):接続を申請する
aws ec2 create-vpc-peering-connection \
--vpc-id vpc-0aaa1111bbbb2222c \
--peer-vpc-id vpc-0ddd3333eeee4444f \
--peer-owner-id 222233334444 \
--peer-region ap-northeast-1 \
--tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=app-to-shared}]' \
--query 'VpcPeeringConnection.VpcPeeringConnectionId' --output text
# アカウントB(アクセプタ):受け取ったIDで承認する
aws ec2 accept-vpc-peering-connection \
--vpc-peering-connection-id pcx-0123456789abcdef0 \
--region ap-northeast-1
# どちらの側でも:状態が active になったか確認する
aws ec2 describe-vpc-peering-connections \
--vpc-peering-connection-ids pcx-0123456789abcdef0 \
--query 'VpcPeeringConnections[0].Status.Code' --output text
クロスリージョンの場合、承認コマンドはアクセプタVPCのリージョンを --region で指定して実行します。リクエスタ側のリージョンで承認しようとしても接続が見つかりません。状態が failed になったときは、CIDRの重複かアカウントIDの誤りをまず疑います。
両側のルートテーブルに相手VPCのCIDR宛てpcxルートを追加する設定
activeになった時点では、どちらのルートテーブルにも経路がありません。相手のCIDR宛てをピアリング接続へ向けるルートを、両側の所有者がそれぞれ追加します。
# アカウントA:VPC A のルートテーブルに VPC B(10.20.0.0/16)宛てを追加
aws ec2 create-route \
--route-table-id rtb-0aaa1111bbbb2222c \
--destination-cidr-block 10.20.0.0/16 \
--vpc-peering-connection-id pcx-0123456789abcdef0
# アカウントB:VPC B のルートテーブルに VPC A(10.10.0.0/16)宛てを追加
aws ec2 create-route \
--route-table-id rtb-0ddd3333eeee4444f \
--destination-cidr-block 10.10.0.0/16 \
--vpc-peering-connection-id pcx-0123456789abcdef0
片側だけ追加した状態では、行きのパケットは届いても戻りが返りません。サブネットごとに別のルートテーブルを使っている場合は、通信させたいサブネットに関連付いたテーブルすべてに追加が要ります。相手VPC全体ではなく特定サブネットだけを通したいときは、宛先CIDRをサブネット単位に絞ります。
セキュリティグループ参照とDNS解決オプションでピア間通信を仕上げる設定
同一リージョンでピアVPCのSGを参照する書き方とアカウントID付き指定
ピアのセキュリティグループを参照する手順によると、同一リージョンなら相手VPCのSGをインバウンドの送信元に指定できます。別アカウントのSGはアカウントIDとSG IDを組み合わせて指定し、別リージョンではSG参照が使えないためCIDRで許可します。
# 同一アカウント・同一リージョン:相手のSG IDをそのまま指定
aws ec2 authorize-security-group-ingress \
--group-id sg-0aaa1111bbbb2222c \
--protocol tcp --port 5432 \
--source-group sg-0ddd3333eeee4444f
# 別アカウント・同一リージョン:--group-owner で相手のアカウントIDを添える
aws ec2 authorize-security-group-ingress \
--group-id sg-0aaa1111bbbb2222c \
--protocol tcp --port 5432 \
--source-group sg-0ddd3333eeee4444f \
--group-owner 222233334444
# 別リージョン:SG参照は使えないので相手VPCのCIDRで許可する
aws ec2 authorize-security-group-ingress \
--group-id sg-0aaa1111bbbb2222c \
--protocol tcp --port 5432 \
--cidr 10.20.0.0/16
コンソールでは相手VPCのSGが選択肢に出てこないため、IDを手で入力します。SG参照は相手側でインスタンスが増減しても許可範囲が追従するので、同一リージョンならCIDR指定より運用が楽になります。
DNS解決オプションを両側で有効にしてパブリックDNS名をプライベートIPへ
既定のままだと、相手インスタンスのパブリックDNS名はパブリックIPに解決されます。その結果、通信がPeeringを通らずに向かう先は、インターネット側です。DNS解決の有効化手順では、接続がactiveであること、両VPCでDNSホスト名とDNS解決が有効なこと、リクエスタ側とアクセプタ側の所有者がそれぞれ自分の側を変更することが条件になっています。
# アカウントA(リクエスタ)側の設定
aws ec2 modify-vpc-peering-connection-options \
--vpc-peering-connection-id pcx-0123456789abcdef0 \
--requester-peering-connection-options AllowDnsResolutionFromRemoteVpc=true
# アカウントB(アクセプタ)側の設定
aws ec2 modify-vpc-peering-connection-options \
--vpc-peering-connection-id pcx-0123456789abcdef0 \
--accepter-peering-connection-options AllowDnsResolutionFromRemoteVpc=true
modify-vpc-peering-connection-optionsのリファレンスにはClassicLink向けのオプションも残っていますが、非推奨扱いです。新規構成で使うのは AllowDnsResolutionFromRemoteVpc だけと考えて差し支えありません。この設定は接続作成と同時には指定できない点にも注意が要ります。
TerraformでVPC Peeringを同一アカウント・別アカウントで構築する手順
同一アカウント・同一リージョンはauto_acceptで1リソースに収める構成
同じアカウントの同じリージョン内なら、aws_vpc_peering_connection の auto_accept = true で承認まで1リソースで済みます。ルートは両方向を aws_route で明示します。
resource "aws_vpc_peering_connection" "app_to_shared" {
vpc_id = aws_vpc.app.id
peer_vpc_id = aws_vpc.shared.id
auto_accept = true
requester {
allow_remote_vpc_dns_resolution = true
}
accepter {
allow_remote_vpc_dns_resolution = true
}
tags = { Name = "app-to-shared" }
}
resource "aws_route" "app_to_shared" {
route_table_id = aws_route_table.app_private.id
destination_cidr_block = aws_vpc.shared.cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.app_to_shared.id
}
resource "aws_route" "shared_to_app" {
route_table_id = aws_route_table.shared_private.id
destination_cidr_block = aws_vpc.app.cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.app_to_shared.id
}
宛先CIDRを文字列で書かず aws_vpc.shared.cidr_block で参照しておくと、VPC側のCIDRを変えたときにルートの書き換え漏れが起きません。構文はterraform-provider-aws 6.66系(2026年9月時点)のドキュメントに合わせています。
別アカウントや別リージョンはaccepterリソースを別providerで管理
auto_accept が使えるのは同一アカウントかつ同一リージョンの場合だけです。それ以外は、aws_vpc_peering_connection_accepterのドキュメントのとおり、申請側と承認側を別リソースに分け、承認側はエイリアス付きproviderで相手アカウントに入ります。
provider "aws" {
region = "ap-northeast-1" # アカウントA(リクエスタ)
}
provider "aws" {
alias = "peer"
region = "ap-northeast-3" # アカウントB(アクセプタ・大阪)
assume_role {
role_arn = "arn:aws:iam::222233334444:role/network-admin"
}
}
data "aws_caller_identity" "peer" {
provider = aws.peer
}
resource "aws_vpc_peering_connection" "app_to_partner" {
vpc_id = aws_vpc.app.id
peer_vpc_id = var.partner_vpc_id
peer_owner_id = data.aws_caller_identity.peer.account_id
peer_region = "ap-northeast-3"
auto_accept = false
}
resource "aws_vpc_peering_connection_accepter" "partner" {
provider = aws.peer
vpc_peering_connection_id = aws_vpc_peering_connection.app_to_partner.id
auto_accept = true
}
resource "aws_vpc_peering_connection_options" "requester" {
vpc_peering_connection_id = aws_vpc_peering_connection_accepter.partner.id
requester {
allow_remote_vpc_dns_resolution = true
}
}
resource "aws_vpc_peering_connection_options" "accepter" {
provider = aws.peer
vpc_peering_connection_id = aws_vpc_peering_connection_accepter.partner.id
accepter {
allow_remote_vpc_dns_resolution = true
}
}
DNSオプションのリソースは、承認済みのID(accepter側の id)を参照させて作成順序を保証します。申請側のIDを直接参照すると、承認前にオプション変更が走ってエラーになります。
destroyしても接続が残るaccepterとオプション二重管理の落とし穴
accepterリソースには、destroyしてもTerraformのstateから外れるだけで、接続そのものは削除されないという仕様があります。接続を消すのは申請側の aws_vpc_peering_connection を削除したときです。承認側のコードだけを別リポジトリで管理していると、「消したはずの接続が残っている」状態が生まれます。
もう1つの落とし穴は、DNSなどのオプションを aws_vpc_peering_connection の requester/accepter ブロックと aws_vpc_peering_connection_options の両方に書くことです。プロバイダのドキュメントは同じ接続のオプションを両方で管理しないよう求めており、書いてしまうとplanのたびに差分が出続けます。クロスアカウント構成ではoptionsリソース側に寄せると決めてしまうのが無難です。
VPC Peeringの料金:同一AZ無料とAZ間・リージョン間転送で課金される条件
2021年5月からの同一AZ無料はAZ名でなくAZ IDで判定するのが要点
VPC Peeringには接続単位の時間料金がありません。掛かるのは転送量だけです。2021年5月の料金改定の告知で、同じアベイラビリティゾーン内にとどまる転送は無料になり、AZをまたぐ転送は従来どおりリージョン内データ転送料金で課金されると示されました。リージョン間の接続では、リージョン間データ転送料金が掛かります。
見落としやすいのが「同じAZ」の判定です。ap-northeast-1a のようなAZ名はアカウントごとに実体の割り当てが異なるため、別アカウント同士ではAZ名が同じでも物理的には別AZということがあります。告知でも、アカウント間で一意に識別するにはAZ IDを使うよう案内されています。
# 両方のアカウントで実行し、ZoneId(例:apne1-az1)が一致するサブネット同士を通信させる
aws ec2 describe-availability-zones --region ap-northeast-1 \
--query 'AvailabilityZones[].[ZoneName,ZoneId]' --output table
通信量の多いアプリとDBを別アカウントに分ける場合は、ZoneIdをそろえた配置にするだけでAZ間転送料金を消せます。
2025年4月に増えた請求の使用タイプでピアリング転送量を追う方法
以前はPeeringの転送量が他のAZ間転送と同じ行に混ざり、請求書から切り出せませんでした。2025年4月の請求簡素化の告知で、Cost ExplorerとCost and Usage Reportに Region_Name-VpcPeering-In/Out-Bytes という使用タイプが追加されています。料金そのものは変わっていません。
Cost Explorerで使用タイプに VpcPeering を含む行を絞り込めば、Peering経由のAZ間転送だけを月次で追えます。Transit Gatewayへの移行を検討するときも、この数字が比較の起点になります。
疎通しないときの切り分け:ルート・SG・NACL・DNSを順に確認する手順
activeなのに通らないときに上から順に確認する5つのチェック項目
接続がactiveでも通信できない原因は、ほぼ次のどれかです。上から順に見ると、手戻りなく原因にたどり着けます。
- 送信元サブネットのルートテーブルに、相手CIDR宛ての
pcx-ルートがあるか - 相手側サブネットのルートテーブルにも、戻りの経路があるか
- 受信側のSGが送信元のSGかCIDRを許可しているか(クロスリージョンでSG参照を書いていないか)
- 両側のネットワークACLが、戻りのエフェメラルポート(1024〜65535)まで許可しているか
- ホスト名で接続している場合、DNS解決オプションが両側で有効になっているか
5番目は症状が紛らわしく、pingはIPで通るのにアプリケーションだけ接続できないという形で出ます。nslookup で相手の名前がパブリックIPを返していれば、DNSオプションの設定漏れです。
ピア接続の削除後に残るstaleなSGルールの検出コマンドと削除手順
相手のSGを参照したルールは、接続を削除しても自動では消えず、stale(無効)なルールとして残ります。公式ドキュメントでも、手動で削除する必要があると書かれています。
# VPC A に残っている無効なSGルールを一覧する
aws ec2 describe-stale-security-groups --vpc-id vpc-0aaa1111bbbb2222c
# 見つかったルールを削除する(例:5432番の相手SG参照)
aws ec2 revoke-security-group-ingress \
--group-id sg-0aaa1111bbbb2222c \
--protocol tcp --port 5432 \
--source-group sg-0ddd3333eeee4444f \
--group-owner 222233334444
同じVPC同士で接続を作り直すとstale表示は解除されますが、意図しない許可が復活することにもなります。接続を廃止するときは、ルートとSGルールの削除を同じ作業票に含めておきます。
PeeringとTransit Gatewayの使い分けを接続数とCIDRで決める基準
VPCが4つ以下でCIDRが重ならない構成ならPeeringを採用する理由
すべてのVPCを相互につなぐ場合、必要な接続数はVPC数をnとしてn×(n−1)÷2本です。4つなら6本、5つで10本、10個になると45本まで増え、1VPCあたり既定50本のクォータにも近づきます。ルートテーブルの行数も同じ割合で増えます。
判断は言い切ります。つなぐVPCが4つ以下、CIDRが重ならない、オンプレミスとの接続を相手VPCと共有しない、の3条件がそろうならPeeringを採用します。時間料金が無く同一AZなら転送も無料で、Transit Gatewayのアタッチメント料金を払う理由がありません。2アカウント間でアプリとDBをつなぐだけ、という構成はこの典型です。比較の詳細はAWS Transit Gatewayの仕組みとVPC Peeringとの違いで整理しています。
オンプレ接続や共通のNAT出口が要るなら最初からTransit Gateway
逆に、次のどれかに当てはまるならPeeringは採用しません。VPCが今後5つ以上に増える見込みがある、オンプレミスへのVPNやDirect Connectを複数VPCで共有したい、インターネット出口のNATを1か所に集約したい、のいずれかです。Peeringはエッジ間ルーティングを許さないため、あとから集約しようとしても構成を組み直すしかありません。
Peeringで始めて後から移行すると、ルート・SG・DNSのすべてを二重に持つ移行期間が発生します。増える見込みが見えているなら、最初からTransit Gatewayで組むほうが、手戻りを小さく抑えられる構成です。複数アカウントでの具体的な組み方はTransit Gatewayのクロスアカウント構築手順(TerraformとRAM共有)にまとめています。
CIDRが重複する他社連携はPeering不可でPrivateLinkへ切り替える
買収した会社のVPCや取引先のVPCは、どちらも10.0.0.0/16で作られているといったCIDR重複がよく起きます。この場合、Peeringは作成時点で拒否されます。CIDRを振り直すにはサブネットごと作り替える必要があり、現実的な選択肢になりません。
公開したいのが特定のAPIやサービスだけなら、ネットワーク同士をつながずにサービス単位で公開する方式に切り替えます。単一サービスの公開ならAWS PrivateLinkの仕組みと採用判断、複数のサービスをまとめて扱うならAmazon VPC Latticeのサービスネットワークが候補です。どの方式が合うか判断しきれない、既存のアカウント構成ごと見直したいという場合は、クラウドのインフラ構築支援で現状の経路図から一緒に整理します。
VPC Peeringの設定・料金・制約についてよくある質問
VPC Peering(VPCピアリング)の設定や運用で、実装者からよく挙がる質問に答えます。
VPC Peeringは接続を作るだけで時間課金や固定料金がかかりますか?
かかりません。VPC Peeringには接続単位の時間料金や固定料金が無く、課金対象は転送したデータ量だけです。2021年5月以降、同一AZ内の転送は無料で、AZをまたぐ転送はリージョン内データ転送料金、リージョン間の接続はリージョン間データ転送料金になります。別アカウント同士で同一AZかどうかを判定するときは、AZ名ではなくAZ IDで確認してください。
別のAWSアカウントや別リージョンのVPCともピアリング接続できますか?
できます。接続が有効になる条件は、申請時にアクセプタ側のアカウントIDとリージョンを指定し、相手側の所有者による承認を得ることです。ただしクロスリージョンでは、相手のセキュリティグループを参照できずCIDRで許可する必要があり、MTU上限も8500バイトに下がります。プライベートDNS名で通信させるなら、DNS解決オプションを両側で有効にしておきます。
3つのVPCをピアリングでつなぐと、端のVPC同士も通信できますか?
通信できません。VPC Peeringは推移的な関係に対応しておらず、AとB、AとCをつないでも、BからAを経由してCへは届きません。BとCを通信させたい場合は、BとCの間にも接続を作ります。VPCの数が増えて全体を相互接続したいなら、接続数が掛け算で増えるため、Transit Gatewayのようなハブ型の構成を検討したほうが管理しやすくなります。
ピアリング先のVPCにあるNATゲートウェイ経由でインターネットに出られますか?
出られません。AWSの制約として、相手VPCのインターネットゲートウェイ、NATデバイス、VPN、Direct Connect、S3向けゲートウェイエンドポイントは、ピアリング先から利用できないと定められています。インターネット出口やオンプレミス接続を複数VPCで共有したいなら、Transit Gatewayを中心にした構成に切り替える必要があります。
CIDRが重複しているVPC同士をどうしても接続したいときはどうすればよいですか?
VPC Peeringでは接続できません。重複するCIDRが1つでもあれば作成時点で拒否されます。選択肢は、片方のVPCを重ならないCIDRで作り直して移行するか、ネットワーク同士をつながずにサービス単位で公開するかです。後者なら、特定のAPIだけを公開するAWS PrivateLinkや、複数サービスをまとめて扱うAmazon VPC Latticeが使えます。
関連記事
- AWS Transit Gatewayとは|仕組み・VPC Peeringとの違い・料金を解説:VPCが増えたときに移る先のハブ型接続と、Peeringとの比較
- Transit Gatewayクロスアカウント構築手順|TerraformとRAM共有:複数アカウントをハブでつなぐ場合のTerraform実装
- CIDRとは?表記の読み方と計算方法・サブネット設計とAWS VPCでの使い方を実装者向けに解説:Peeringの前提になる重ならないCIDRの切り方
- AWSのネットワーク接続方式まとめ|VPC内・VPC間・オンプレ・インターネットの選び分け:Peeringを含む接続方式全体の見取り図
- VPCエンドポイントとは|2種類の違いとNATゲートウェイとの料金比較・損益分岐点:ピア先のゲートウェイエンドポイントを借りられないときの代替