AWS Cloud WANとオンプレミスとが複数経路で接続されている環境で非対称ルーティングを防ぐためにはRouting Policyを用いた制御を検討しよう

AWS Cloud WANとオンプレミスとが複数経路で接続されている環境で非対称ルーティングを防ぐためにはRouting Policyを用いた制御を検討しよう

Routing Policyを用いてトラフィックをコントロールしよう
2026.08.17

AWS Cloud WANとオンプレミスとが複数経路で接続されているけど非対称ルーティングが気になる

こんにちは、のんピ(@non____97)です。

皆さんはAWS Cloud WANとオンプレミスとが複数経路で接続されてる環境において、非対称ルーティングが気になったことはありますか? 私はあります。

非対称ルーティングとなることで、ネットワークレイテンシーが増大してしまいパフォーマンスが劣化してしまうことはもちろん、途中のネットワーク機器がそもそも非対称ルーティングをサポートしていない場合は通信断となってしまいます。

これは避けたいです。

オンプレミスからAWSへの通信についてはオンプレミスルーター側でAS_PATH PrependやLocal Preferenceを用いてコントロールすることで、どのパスを抜けていくのか自由にコントロールすることが可能です。

AWSからオンプレミスへの通信については長らくAWS側の設定でのコントロールが難しい要素でしたが、Cloud WANをお使いの場合はRouting Policyを用いることによって簡単に制御をすることが可能です。

https://aws.amazon.com/jp/blogs/news/networking-and-content-delivery-aws-cloud-wan-routing-policy-fine-grained-controls-for-your-global-network-part-1/

https://aws.amazon.com/jp/blogs/news/networking-and-content-delivery-aws-cloud-wan-routing-policy-real-world-global-network-scenarios-part-2/

通常であればオンプレミスルーター側でAS_PATH PrependやMEDを設定して、AWSからオンプレミスへの通信経路をコントロールしたいところですが、何らかの理由でオンプレミスルーターのコントロールが難しい場面に役立ちそうです。

実際に使ってみます。

いきなりまとめ

  • AWS Cloud WANとオンプレミスを複数経路 (東京/大阪、バージニア北部/オレゴン) で接続すると、行きと帰りでBGPパスアトリビュートが同一になり、先に受信したルートなど構築タイミングに依存する要素でベストパスが決まってしまうため、非対称ルーティングが発生する
    • AWS公式ドキュメントでも、AS_PATH長やMEDが同一の場合は最終的に deterministically random に選択されると明記されている
  • AWSからオンプレミスへの通信はRouting PolicyのAS_PATH Prependで制御できる
    • マッチ条件を「優先度を落としたいリージョンのCNEのASNを含む」という単一条件にすると、そのリージョン自身が発信元となるローカルな経路まで巻き込んでしまい、本来最短のはずの自リージョン宛の経路まで他リージョン経由と同じ扱いになってしまう
      • CNEは経路を再広告するたびに自分のASNを先頭に足すため、AS_PATHだけでは「自身が発信したルートか」「中継しただけのルートか」を区別できないため
    • 「広告されてきた経路のAS_PATH内に対応するオンプレミスネットワークのASNが含まれている場合」というAND条件を追加する形で対応をする
      • associate-routing-policy を組み合わせる設計であれば、マッチ条件はオンプレミスネットワークのASNのみで十分。ただしAND条件を一つ加えておくと、ルール単独でも意図が伝わりやすくなる
  • associate-routing-policy の適用範囲を最短経路のペアだけに絞ると、TGWアタッチメントを削除するなどして最短経路が失われた際に、迂回経路にはAS_PATH Prependが効かず遠回りの経路を選んでしまう
    • 回避するには、非優先リージョンから優先リージョンへ直接広告するペア (大阪→東京、オレゴン→バージニア北部など) にも associate-routing-policy を適用しておく必要がある
    • 必要な associate-routing-policy の数は「非優先CNEの数 × (全リージョン数 − 1)」で求まる。オンプレミスグループが2つなら6、3つなら15、4つなら28、5つなら45と増えていく
  • RIBは自CNEがこれから適用するRouting Policyについては未反映の状態を返すが、他CNE経由で届いた経路にはそのCNEが既に適用した結果が反映されて見える
  • Cloud WANとのアタッチメントを削除しても、適切なRouting Policyを設定していれば、意図した迂回経路に切り替わり、アタッチメントを再作成すれば元の経路に戻る

検証環境

検証環境は以下のとおりです。

architecture.drawio.png

日本側は東京/大阪リージョンで、アメリカ側はバージニア北部/オレゴンリージョンで構成をしています。東京とバージニア北部リージョンそれぞれにオンプレミス相当のネットワークとして、VPCおよびVPNルーターのEC2インスタンスを動作させています。

いずれのVPNルーターもSite-to-Site VPNを使って東京/大阪、バージニア北部/オレゴンのTransit Gatewayに接続しています。オンプレミス相当のネットワークから2本Site-to-Site VPNの接続が伸びているため、バージニア北部/オレゴン/アメリカオンプレミス相当ネットワークから日本オンプレミス相当ネットワーク、およびその逆の場合において、どちらのSite-to-Site VPNを通るのか判断が難しい状況を作り出しました。

このとき、Routing PolicyでAS_PATH Prependをしない場合/する場合とでルート情報がどのように変化するのか、非対称ルーティングの発生および解消の様子を確認していきます。

全てAWS CDKで構築しました。使用したコードは以下リポジトリに保存しています。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn

Routing PolicyでAS_PATH Prependを行わない場合

各種リソースおよび各セグメントのルート情報の確認

動作確認をする前に、各種リソースおよび各セグメントのルート情報の確認をします。

各種リソースは以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/resource-list.log

Core Network Policyは以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/baseline-corepolicy.json

各セグメントのルート情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/baseline-fib.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/baseline-rib.log

加えて、東京リージョンおよび大阪リージョンの各VPNルーターEC2インスタンスから見えるBGPの情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/baseline-us-router.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/baseline-jp-router.log

これを確認すると、以下で非対称ルーティングが発生していることが分かります。

  1. Cloud WAN接続の東京リージョンVPCとバージニア北部オンプレミス相当VPC間
    • Cloud WAN接続の東京リージョンVPC → バージニア北部オンプレミス相当VPC の通信の場合 : オレゴンリージョンTGWを経由
      • 東京リージョンのCNEのFIBを確認すると、10.200.0.0/16のネクストホップがEDGE:us-west-2となっているため
    • バージニア北部オンプレミス相当VPC → 東京リージョンVPC の通信の場合 : バージニア北部リージョンTGWを経由
      • VPNルーターにて、10.0.0.0/16宛のベストパスが169.254.30.1と バージニア北部リージョンTGWとのSite-to-Site VPNのトンネルを選択しているため
  2. Cloud WAN接続の大阪リージョンVPCとバージニア北部オンプレミス相当VPC間
    • Cloud WAN接続の大阪リージョンVPC → バージニア北部オンプレミス相当VPC の通信の場合 : オレゴンリージョンTGWを経由
      • 大阪リージョンのCNEのFIBを確認すると、10.200.0.0/16のネクストホップがEDGE:us-west-2となっているため
    • バージニア北部オンプレミス相当VPC → Cloud WAN接続の大阪リージョンVPC の通信の場合 : バージニア北部リージョンTGWを経由
      • VPNルーターにて、10.0.0.0/16宛のベストパスが169.254.30.1と バージニア北部リージョンTGWとのSite-to-Site VPNのトンネルを選択しているため

前者を図示すると以下のようになります。

architecture-asymmetric-routing-tokyo-vpc-virginia-onpremises.drawio.png

非対称ルーティングとなっている理由はどちらのパスも行きと帰りそれぞれLP、AWS_PATH長、MEDなどのBGPパスアトリビュートが同一であり、先に受信したルートやルーターIDなどで判断してしまっているからです。「特に先に受信したルート」など構築のタイミングやBGPネイバーの切り替えなどによって容易に変動してしまう要素です。あまりこちらに頼りたくはありません。運用者側で制御をしたいところです。

architecture-bgp-route-advertisement-tokyo-vpc-virginia-onpremises.drawio.png

ちなみに、一般的にはBGPのベストパスは以下のように決定することが多いように感じます。

  1. 最も高いWEIGHTを持つパス (Cisco独自)
  2. 最も高いLOCAL_PREFを持つパス
  3. network または aggregate BGP サブコマンドによって、あるいはIGPからの再配布を通じて、ローカルで発信されたパス
  4. 最短のAS_PATHを持つパス
  5. 最小のオリジンタイプを持つパス
  6. 最小のMulti-Exit Discriminator(MED)を持つパス
  7. iBGPパスよりもeBGPパス
  8. BGPネクストホップへの最小のIGPメトリックを持つパス
  9. マルチパスがBGPマルチパス用にルーティングテーブルでインストールされる必要があるかどうか判断
  10. 両方のパスが外部のときは、先に受信したパス
  11. 最小のルータIDを持つBGPルータから送られたルート
  12. 発信元IDまたはルータIDが複数のパスで同じ場合は、最小のクラスタリスト長を持つパス
  13. 最小の隣接ルータアドレスから送られたパス

参考 : BGPベストパスアルゴリズムの選択 - Cisco

AWS公式ドキュメントではCloud WANのルートの優先順位については以下のように紹介されています。

  1. The most specific route for the destination
  2. For routes with the same destination IP address, but different targets, the following route priority is used:
    1. Static routes
    2. VPC-propagated routes in the same Region.
    3. For dynamic routes received at the core network with an unequal AS path length and/or MED BGP attributes, Cloud WAN evaluates them in the following order:
      1. AS path length
      2. MED
    4. For dynamic routes received at the core network with equal AS path length and MED BGP attributes, Cloud WAN evaluates them in the following order:
      1. Direct Connect gateway-propagated routes.
      2. Cloud WAN Connect-propagated routes in the same Region.
      3. Site-to-Site VPN-propagated routes in the same Region.
      4. Routes propagated from other sources, such as transit gateway peering and core network edges in other remote Regions over the AWS global infrastructure. If identical routes are received from two or more sources, a single attachment will be chosen in a deterministically random manner (this occurs on a per segment/network function group basis so you could see different destinations for the same route across different segment/network function groups).

Route evaluation - AWS Network Manager

Routing PolicyによってLocal Preferenceの設定も可能なところLocal Preferenceについての言及がないのが気になりますが、Cloud WANは同一条件のルートがある場合は最終的にランダムに選択するようです。

実際に疎通確認をして、非対称ルーティングとなっているかどうかを確認してみましょう。

疎通確認

疎通確認をしてみましょう。

まずは非対称ルーティングとなるものからです。

バージニア北部リージョンのオンプレミス相当VPCと東京リージョンTGWに接続しているVPC間の通信です。

$ hostname -i
10.200.1.82

$ ping -c 4 10.10.0.154
PING 10.10.0.154 (10.10.0.154) 56(84) bytes of data.
64 bytes from 10.10.0.154: icmp_seq=1 ttl=121 time=168 ms
64 bytes from 10.10.0.154: icmp_seq=2 ttl=121 time=162 ms
64 bytes from 10.10.0.154: icmp_seq=3 ttl=121 time=162 ms
64 bytes from 10.10.0.154: icmp_seq=4 ttl=121 time=163 ms

--- 10.10.0.154 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 161.839/163.694/168.024/2.539 ms

次に、同様に非対称ルーティングとなるバージニア北部リージョンのオンプレミス相当VPCと大阪リージョンTGWに接続しているVPC間の通信の通信です。

$ ping -c 4 10.11.0.131
PING 10.11.0.131 (10.11.0.131) 56(84) bytes of data.
64 bytes from 10.11.0.131: icmp_seq=1 ttl=121 time=168 ms
64 bytes from 10.11.0.131: icmp_seq=2 ttl=121 time=163 ms
64 bytes from 10.11.0.131: icmp_seq=3 ttl=121 time=163 ms
64 bytes from 10.11.0.131: icmp_seq=4 ttl=121 time=163 ms

--- 10.11.0.131 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 162.725/164.085/167.857/2.179 ms

$ date
Thu Aug 13 06:35:22 UTC 2026

以降は対象ルーティングになるものの通信をしていきます。

バージニア北部リージョンのオンプレミス相当VPCと東京リージョンのオンプレミス相当VPCです。

$ ping -c 4 10.100.1.78 
PING 10.100.1.78 (10.100.1.78) 56(84) bytes of data.
64 bytes from 10.100.1.78: icmp_seq=1 ttl=120 time=170 ms
64 bytes from 10.100.1.78: icmp_seq=2 ttl=120 time=162 ms
64 bytes from 10.100.1.78: icmp_seq=3 ttl=120 time=162 ms
64 bytes from 10.100.1.78: icmp_seq=4 ttl=120 time=162 ms

--- 10.100.1.78 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 162.018/164.088/169.988/3.407 ms

次に、バージニア北部リージョンのオンプレミス相当VPCとCloud WANに接続している東京リージョンVPC間の通信です。

$ ping -c 4 10.0.0.170
PING 10.0.0.170 (10.0.0.170) 56(84) bytes of data.
64 bytes from 10.0.0.170: icmp_seq=1 ttl=122 time=167 ms
64 bytes from 10.0.0.170: icmp_seq=2 ttl=122 time=161 ms
64 bytes from 10.0.0.170: icmp_seq=3 ttl=122 time=165 ms
64 bytes from 10.0.0.170: icmp_seq=4 ttl=122 time=188 ms

--- 10.0.0.170 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 161.498/170.380/188.148/10.436 ms

バージニア北部リージョンのオンプレミス相当VPCとCloud WANに接続している大阪リージョンVPC間の通信です。

$ ping -c 4 10.1.0.182
PING 10.1.0.182 (10.1.0.182) 56(84) bytes of data.
64 bytes from 10.1.0.182: icmp_seq=1 ttl=122 time=167 ms
64 bytes from 10.1.0.182: icmp_seq=2 ttl=122 time=164 ms
64 bytes from 10.1.0.182: icmp_seq=3 ttl=122 time=164 ms
64 bytes from 10.1.0.182: icmp_seq=4 ttl=122 time=164 ms

--- 10.1.0.182 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 163.552/164.468/167.165/1.556 ms

バージニア北部リージョンのオンプレミス相当VPCとCloud WANに接続しているバージニア北部リージョンVPC間の通信の通信です。

$ ping -c 4 10.2.0.17
PING 10.2.0.17 (10.2.0.17) 56(84) bytes of data.
64 bytes from 10.2.0.17: icmp_seq=1 ttl=123 time=5.40 ms
64 bytes from 10.2.0.17: icmp_seq=2 ttl=123 time=2.94 ms
64 bytes from 10.2.0.17: icmp_seq=3 ttl=123 time=2.81 ms
64 bytes from 10.2.0.17: icmp_seq=4 ttl=123 time=2.69 ms

--- 10.2.0.17 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 2.688/3.460/5.398/1.122 ms

最後にバージニア北部リージョンのオンプレミス相当VPCとCloud WANに接続しているオレゴンリージョンVPC間の通信です。

$ ping -c 4 10.3.0.94
PING 10.3.0.94 (10.3.0.94) 56(84) bytes of data.
64 bytes from 10.3.0.94: icmp_seq=1 ttl=123 time=65.5 ms
64 bytes from 10.3.0.94: icmp_seq=2 ttl=123 time=63.5 ms
64 bytes from 10.3.0.94: icmp_seq=3 ttl=123 time=62.4 ms
64 bytes from 10.3.0.94: icmp_seq=4 ttl=123 time=62.1 ms

--- 10.3.0.94 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 62.071/63.357/65.451/1.320 ms

TGW Flow Logsの確認

TGW Flow Logsにて、どの通信でどのTGWを通っているのかを確認し、確かに非対称ルーティングであることを確認しましょう。

ダッシュボードでは以下のとおりです。

1.平常時のダッシュボードログ.png

分かりづらいので以下のように吹き出しと色付けをしてみました。

3.平常時のダッシュボードログ_吹き出し設定.png

はい、事前に確認したとおり、以下の通信については非対称ルーティングが発生した関係で経由しているTGWが3つとなっています。

  • (図中赤枠) バージニア北部リージョンのオンプレミス相当VPCと東京リージョンTGWに接続しているVPC間の通信
    • 行き : バージニア北部 → 東京
    • 戻り : 東京 → オレゴン
  • (図中緑枠)バージニア北部リージョンのオンプレミス相当VPCと大阪リージョンTGWに接続しているVPC間の通信
    • 行き : バージニア北部 → 大阪
    • 戻り : 大阪 → オレゴン

Routing PolicyでAS_PATH Prependを行う場合

Routing Policyの適用 (1回目)

それではRouting Policyで経路制御をしてみましょう。

今回は東京/大阪リージョンの場合は、東京リージョンを優先させ、バージニア北部/オレゴンリージョンの場合は、バージニア北部リージョンを優先させます。

対処として、大阪リージョンもしくはオレゴンリージョンのCNEのASNがAS_PATHに含まれている場合は、4200000001をAS_PATH Prependをすることによって優先度を落とします。

architecture-as-path-prepend.drawio.png

Local Preferenceを用いて東京リージョンおよびバージニア北部リージョンのルートの優先度を上げる形で制御しても良いです。

lib/network-config.tsにてROUTING_POLICY_MODEprependに変更してデプロイします。

> cdk diff --no-change-set
Stack CloudWanRoutingCoreStack
Resources
[~] AWS::NetworkManager::CoreNetwork CoreNetwork CoreNetwork
 └─ [~] PolicyDocument
     ├─ [+] Added: .routing-policies
     └─ [+] Added: .segment-actions
.
.
(中略)
.
.
  Number of stacks with differences: 1

Core Network Policyは以下のようになります。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy1-corepolicy.json

Routing Policyおよびassociate-routing-policyの記法は以下AWS公式ドキュメントおよびGitHub上に公開されているaws-samplesが参考になります。

https://docs.aws.amazon.com/ja_jp/network-manager/latest/cloudwan/cloudwan-routing-policies.html

https://docs.aws.amazon.com/ja_jp/network-manager/latest/cloudwan/cloudwan-policies-json.html#cloudwan-attachment-routing-policy-rules-json

https://github.com/aws-samples/aws-cloud-wan-blueprints/blob/main/policy/7-routing_policies.md

https://github.com/aws-samples/aws-cloud-wan-blueprints/blob/main/policy/8-edge_location_associations.md

https://github.com/aws-samples/aws-cloud-wan-blueprints/blob/main/policy/9-attachment_routing_policy_rules.md

個人的にはaws-samplesの方が例文および各パラメーターが詳細に記載されているので、好みです。

各セグメントのルート情報の確認をします。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/baseline-fib.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/baseline-rib.log

分かりやすくRouting Policy適用前後でdiffをすると以下のとおりです。

fib
> diff -u "evidence/20260813/baseline-fib.log" "evidence/20260813/policy1-fib.log"
--- evidence/20260813/baseline-fib.log   2026-08-13 13:47:30
+++ evidence/20260813/policy1-fib.log     2026-08-13 20:03:15
@@ -21,9 +21,9 @@
 10.10.0.0/16   PROPAGATED  ACTIVE  ap-northeast-1/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-05bb95f4e94ef7700
 10.11.0.0/16   PROPAGATED  ACTIVE  EDGE:ap-northeast-3                         -
 10.12.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
-10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-west-2                              -
+10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
 10.100.0.0/16  PROPAGATED  ACTIVE  ap-northeast-1/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-05bb95f4e94ef7700
-10.200.0.0/16  PROPAGATED  ACTIVE  EDGE:us-west-2                              -
+10.200.0.0/16  PROPAGATED  ACTIVE  EDGE:us-east-1                              -

 ===== SEGMENT=workload  EDGE=ap-northeast-3 =====
 CIDR           TYPE        STATE   NEXT-HOP                                    ATTACHMENT
@@ -34,9 +34,9 @@
 10.10.0.0/16   PROPAGATED  ACTIVE  EDGE:ap-northeast-1                         -
 10.11.0.0/16   PROPAGATED  ACTIVE  ap-northeast-3/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-025a7eb9f5ee9cf35
 10.12.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
-10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-west-2                              -
+10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
 10.100.0.0/16  PROPAGATED  ACTIVE  ap-northeast-3/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-025a7eb9f5ee9cf35
-10.200.0.0/16  PROPAGATED  ACTIVE  EDGE:us-west-2                              -
+10.200.0.0/16  PROPAGATED  ACTIVE  EDGE:us-east-1                              -

 ===== SEGMENT=workload  EDGE=us-east-1 =====
 CIDR           TYPE        STATE   NEXT-HOP                               ATTACHMENT
rib
> diff -uw "evidence/20260813/baseline-rib.log" "evidence/20260813/policy1-rib.log"
--- evidence/20260813/baseline-rib.log   2026-08-13 13:46:51
+++ evidence/20260813/policy1-rib.log     2026-08-13 20:03:55
@@ -3,29 +3,28 @@
 ===== RIB  SEGMENT=workload  EDGE=ap-northeast-1 =====
 PREFIX         EDGE            SEG           TYPE                         LOCAL-PREF  MED  AS-PATH                  COMMUNITY
 10.0.0.0/16    -               -             vpc                          -           -    -                        -
-10.1.0.0/16    us-east-1       workload  -                            0           100  64522 64521              -
+10.1.0.0/16    us-east-1       workload  -                            0           100  64522 4200000001 64521        -
 10.1.0.0/16    ap-northeast-3  workload  -                            0           100  64521                    -
-10.1.0.0/16    us-west-2       workload  -                            0           100  64523 64521              -
+10.1.0.0/16    us-west-2       workload  -                            0           100  64523 4200000001 64521        -
 10.2.0.0/16    us-east-1       workload  -                            0           100  64522                    -
 10.2.0.0/16    ap-northeast-3  workload  -                            0           100  64521 64522              -
 10.2.0.0/16    us-west-2       workload  -                            0           100  64523 64522              -
 10.3.0.0/16    us-east-1       workload  -                            0           100  64522 64523              -
-10.3.0.0/16    ap-northeast-3  workload  -                            0           100  64521 64523              -
 10.3.0.0/16    us-west-2       workload  -                            0           100  64523                    -
 10.10.0.0/16   -               -             transit-gateway-route-table  0           100  64512                    -
-10.11.0.0/16   us-east-1       workload  -                            0           100  64522 64521 64513        -
+10.11.0.0/16   us-east-1       workload  -                            0           100  64522 4200000001 64521 64513  -
 10.11.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64513              -
-10.11.0.0/16   us-west-2       workload  -                            0           100  64523 64521 64513        -
+10.11.0.0/16   us-west-2       workload  -                            0           100  64523 4200000001 64521 64513  -
 10.12.0.0/16   us-east-1       workload  -                            0           100  64522 64514              -
 10.12.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64522 64514        -
 10.12.0.0/16   us-west-2       workload  -                            0           100  64523 64522 64514        -
 10.13.0.0/16   us-east-1       workload  -                            0           100  64522 64523 64515        -
-10.13.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64523 64515        -
+10.13.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64522 64523 64515       -
 10.13.0.0/16   us-west-2       workload  -                            0           100  64523 64515              -
 10.100.0.0/16  -               -             transit-gateway-route-table  0           100  64512 65000              -
 10.100.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64513 65000        -
 10.200.0.0/16  us-east-1       workload  -                            0           100  64522 64514 65001        -
-10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64523 64515 65001  -
+10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64522 64514 65001       -
 10.200.0.0/16  us-west-2       workload  -                            0           100  64523 64515 65001        -
 ===== RIB  SEGMENT=workload  EDGE=ap-northeast-3 =====
 PREFIX         EDGE            SEG           TYPE                         LOCAL-PREF  MED  AS-PATH                  COMMUNITY
@@ -37,7 +36,7 @@
 10.2.0.0/16    ap-northeast-1  workload  -                            0           100  64520 64522              -
 10.2.0.0/16    us-west-2       workload  -                            0           100  64523 64522              -
 10.3.0.0/16    us-east-1       workload  -                            0           100  64522 64523              -
-10.3.0.0/16    ap-northeast-1  workload  -                            0           100  64520 64523              -
+10.3.0.0/16    ap-northeast-1  workload  -                            0           100  64520 4200000001 64523   -
 10.3.0.0/16    us-west-2       workload  -                            0           100  64523                    -
 10.10.0.0/16   us-east-1       workload  -                            0           100  64522 64520 64512        -
 10.10.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64512              -
@@ -47,14 +46,14 @@
 10.12.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64522 64514        -
 10.12.0.0/16   us-west-2       workload  -                            0           100  64523 64522 64514        -
 10.13.0.0/16   us-east-1       workload  -                            0           100  64522 64523 64515        -
-10.13.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64523 64515        -
+10.13.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64522 64523 64515  -
 10.13.0.0/16   us-west-2       workload  -                            0           100  64523 64515              -
 10.100.0.0/16  us-east-1       workload  -                            0           100  64522 64520 64512 65000  -
 10.100.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64512 65000        -
 10.100.0.0/16  us-west-2       workload  -                            0           100  64523 64520 64512 65000  -
 10.100.0.0/16  -               -             transit-gateway-route-table  0           100  64513 65000              -
 10.200.0.0/16  us-east-1       workload  -                            0           100  64522 64514 65001        -
-10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64523 64515 65001  -
+10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64522 64514 65001  -
 10.200.0.0/16  us-west-2       workload  -                            0           100  64523 64515 65001        -
 ===== RIB  SEGMENT=workload  EDGE=us-east-1 =====
 PREFIX         EDGE            SEG           TYPE                         LOCAL-PREF  MED  AS-PATH                  COMMUNITY
@@ -63,27 +62,23 @@
 10.0.0.0/16    us-west-2       workload  -                            0           100  64523 64520              -
 10.1.0.0/16    ap-northeast-3  workload  -                            0           100  64521                    -
 10.1.0.0/16    ap-northeast-1  workload  -                            0           100  64520 64521              -
-10.1.0.0/16    us-west-2       workload  -                            0           100  64523 64521              -
+10.1.0.0/16    us-west-2       workload  -                            0           100  64523 4200000001 64521        -
 10.2.0.0/16    -               -             vpc                          -           -    -                        -
-10.3.0.0/16    ap-northeast-3  workload  -                            0           100  64521 64523              -
-10.3.0.0/16    ap-northeast-1  workload  -                            0           100  64520 64523              -
+10.3.0.0/16    ap-northeast-3  workload  -                            0           100  64521 4200000001 64523        -
+10.3.0.0/16    ap-northeast-1  workload  -                            0           100  64520 4200000001 64523        -
 10.3.0.0/16    us-west-2       workload  -                            0           100  64523                    -
 10.10.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64520 64512        -
 10.10.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64512              -
 10.10.0.0/16   us-west-2       workload  -                            0           100  64523 64520 64512        -
 10.11.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64513              -
 10.11.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64521 64513        -
-10.11.0.0/16   us-west-2       workload  -                            0           100  64523 64521 64513        -
+10.11.0.0/16   us-west-2       workload  -                            0           100  64523 4200000001 64521 64513  -
 10.12.0.0/16   -               -             transit-gateway-route-table  0           100  64514                    -
-10.13.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64523 64515        -
-10.13.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64523 64515        -
 10.13.0.0/16   us-west-2       workload  -                            0           100  64523 64515              -
 10.100.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64513 65000        -
 10.100.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64512 65000        -
 10.100.0.0/16  us-west-2       workload  -                            0           100  64523 64520 64512 65000  -
 10.200.0.0/16  -               -             transit-gateway-route-table  0           100  64514 65001              -
-10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64523 64515 65001  -
-10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64523 64515 65001  -
 10.200.0.0/16  us-west-2       workload  -                            0           100  64523 64515 65001        -
 ===== RIB  SEGMENT=workload  EDGE=us-west-2 =====
 PREFIX         EDGE            SEG           TYPE                         LOCAL-PREF  MED  AS-PATH                  COMMUNITY
@@ -92,7 +87,7 @@
 10.0.0.0/16    us-east-1       workload  -                            0           100  64522 64520              -
 10.1.0.0/16    ap-northeast-1  workload  -                            0           100  64520 64521              -
 10.1.0.0/16    ap-northeast-3  workload  -                            0           100  64521                    -
-10.1.0.0/16    us-east-1       workload  -                            0           100  64522 64521              -
+10.1.0.0/16    us-east-1       workload  -                            0           100  64522 4200000001 64521        -
 10.2.0.0/16    ap-northeast-1  workload  -                            0           100  64520 64522              -
 10.2.0.0/16    ap-northeast-3  workload  -                            0           100  64521 64522              -
 10.2.0.0/16    us-east-1       workload  -                            0           100  64522                    -
@@ -102,7 +97,7 @@
 10.10.0.0/16   us-east-1       workload  -                            0           100  64522 64520 64512        -
 10.11.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64521 64513        -
 10.11.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64513              -
-10.11.0.0/16   us-east-1       workload  -                            0           100  64522 64521 64513        -
+10.11.0.0/16   us-east-1       workload  -                            0           100  64522 4200000001 64521 64513  -
 10.12.0.0/16   ap-northeast-1  workload  -                            0           100  64520 64522 64514        -
 10.12.0.0/16   ap-northeast-3  workload  -                            0           100  64521 64522 64514        -
 10.12.0.0/16   us-east-1       workload  -                            0           100  64522 64514              -
@@ -111,4 +106,6 @@
 10.100.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64513 65000        -
 10.100.0.0/16  us-east-1       workload  -                            0           100  64522 64520 64512 65000  -
 10.200.0.0/16  -               -             transit-gateway-route-table  0           100  64515 65001              -
+10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64522 64514 65001       -
+10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64522 64514 65001       -
 10.200.0.0/16  us-east-1       workload  -                            0           100  64522 64514 65001        -
\ No newline at end of file

はい、10.200.0.0/16のベストパスが意図したとおり、バージニア北部リージョンのTGWになりました。一方で、10.13.0.0/16とオレゴンリージョンのVPCへのベストパスもバージニア北部リージョンのCNEとなってしまっています。これはよろしくありません。直接オレゴンリージョンのCNEを行けばいいものの、迂回する経路となってしまっています。

ちなみに、東京リージョンおよび大阪リージョンの各VPNルーターEC2インスタンスから見えるBGPの情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy1-us-router.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy1-jp-router.log

ちなみに、RIBは本来Routing Policy適用前の情報を返してくれるものですが、他CNEにて評価されたのであろうルートには4200000001とAS_PATH PrependしたAS_PATHとなってしまっています。

The list-core-network-routing-information API shows the routing information before routing policies have been applied

AWS Cloud WAN Routing policies - AWS Network Manager

ここから「自CNEのRIBは、自CNEがこれから適用するRouting Policyについてはまだ反映されていない状態を示す。一方、他CNEを経由して届いた経路については、そのCNEが経路を受信したpeerとの組み合わせでRouting Policyを持っている場合に限り、受信時点で適用した状態で見える。」という挙動をしているものと考えています。

Routing Policyの適用 (2回目)

このような形になってしまった原因は、シンプルにAS_PATH Prependをする条件が不適切だったためです。当初の実装は、AS_PATH Prependの対象を「AS_PATH に オレゴンや大阪のCNEのASN が含まれるかどうか」という単一の条件だけで判定していました。

しかし、CNEのASNは、そのCNEが経路の発信元である場合だけでなく、他のCNEから学習した経路をただ中継しているだけの場合にも、同じようにAS_PATHに含まれます。CNEは経路を再広告するたびに自分の ASNを先頭に足すため、AS_PATHはそのASにおいて「AS内で発信したルートか」と「中継しただけのルートか」を区別する情報を持っていません。つまり「オレゴンや大阪のCNEのように優先度を落としたいリージョンのASNを含む」という条件だけでは、他リージョンの経路をただ中継しただけの場合と、非優先リージョン自身のローカルな経路を区別できませんでした。

この結果、非優先リージョン自身が発信元となる経路までAS_PATH Prependの対象に含まれてしまいました。これにより、本来なら最短で選ばれるはずの自リージョン宛の経路が、他リージョン経由の経路と変わらないようになってしまいました。

architecture-as-path-prepend-unintended-routes.drawio.png

対応として、「広告されてきた経路のAS_PATH内に対応するオンプレミスネットワークのASNが含まれている場合」というAND条件を付け加えました。これにより、大阪やオレゴンなど優先度を落としたいリージョンのTGWを介して、オンプレミスネットワークから広告されてきたルートにのみAS_PATH Prependがなされます。その結果、日本側のCNEから見たアメリカ側のネットワークへのベストパスはバージニア北部CNEに、アメリカ側のCNEから見た日本側のネットワークへのベストパスは東京CNE側になりますが、非優先リージョンのCNE由来のルートについては非優先リージョンのCNEへのルートがベストパスとなります。

architecture-as-path-prepend-condition-adjusted-onpremises-routes.drawio.png

architecture-as-path-prepend-condition-adjusted.drawio.png

なお、Routing Policyのルール定義だけで完結させるのではなく、associate-routing-policyを絡めるのであれば、Routing Policyのマッチ条件は「AS_PATH内に対応するオンプレミスネットワークのASNが含まれている場合」のみで十分です。associate-routing-policyにてルート広告の送信/受信のCNEを指定するため、今回定義したように「大阪リージョンもしくはオレゴンリージョンのCNEのASNがAS_PATHに含まれている場合」という条件をANDで指定しなくとも動作はします。ただし、associate-routing-policyを絡めることを前提に突き進んでしまうと、設計の意図が伝わりにくい場面もあるかと思います。AND条件を一つ追加するだけで、Routing Policyのルール単独で認識の解像度が上がるのであれば個人的には追加しておきたい派です。

実際のCore Network Policyは以下のとおりです。送信がオレゴンリージョンで受信が東京/大阪リージョン、送信が大阪リージョンで受信がバージニア北部/オレゴンリージョンの場合にRouting Policyを適用するようにしています。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-corepolicy.json

この時のルート情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-fib.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-rib.log

FIBをdiffすると、10.13.0.0/16のネクストホップがオレゴンリージョンのCNEとなっています。意図したとおりですね。

> diff -u "evidence/20260813/policy1-fib.log" "evidence/20260813/policy2-fib.log"
--- evidence/20260813/policy1-fib.log     2026-08-14 02:18:56
+++ evidence/20260813/policy2-fib.log    2026-08-14 02:18:56
@@ -21,7 +21,7 @@
 10.10.0.0/16   PROPAGATED  ACTIVE  ap-northeast-1/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-05bb95f4e94ef7700
 10.11.0.0/16   PROPAGATED  ACTIVE  EDGE:ap-northeast-3                         -
 10.12.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
-10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
+10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-west-2                              -
 10.100.0.0/16  PROPAGATED  ACTIVE  ap-northeast-1/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-05bb95f4e94ef7700
 10.200.0.0/16  PROPAGATED  ACTIVE  EDGE:us-east-1                              -

@@ -34,7 +34,7 @@
 10.10.0.0/16   PROPAGATED  ACTIVE  EDGE:ap-northeast-1                         -
 10.11.0.0/16   PROPAGATED  ACTIVE  ap-northeast-3/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-025a7eb9f5ee9cf35
 10.12.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
-10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-east-1                              -
+10.13.0.0/16   PROPAGATED  ACTIVE  EDGE:us-west-2                              -
 10.100.0.0/16  PROPAGATED  ACTIVE  ap-northeast-3/TRANSIT_GATEWAY_ROUTE_TABLE  attachment-025a7eb9f5ee9cf35
 10.200.0.0/16  PROPAGATED  ACTIVE  EDGE:us-east-1                              -

RIBについては、Routing Policyをそもそも適用する前と比較をすると、以下のようになっています。

> diff -uw "evidence/20260813/baseline-rib.log" "evidence/20260813/policy2-rib.log"
--- evidence/20260813/baseline-rib.log   2026-08-13 13:46:51
+++ evidence/20260813/policy2-rib.log    2026-08-13 21:45:41
@@ -25,7 +25,7 @@
 10.100.0.0/16  -               -             transit-gateway-route-table  0           100  64512 65000              -
 10.100.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64513 65000        -
 10.200.0.0/16  us-east-1       workload  -                            0           100  64522 64514 65001        -
-10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64523 64515 65001  -
+10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64522 64514 65001  -
 10.200.0.0/16  us-west-2       workload  -                            0           100  64523 64515 65001        -
 ===== RIB  SEGMENT=workload  EDGE=ap-northeast-3 =====
 PREFIX         EDGE            SEG           TYPE                         LOCAL-PREF  MED  AS-PATH                  COMMUNITY
@@ -54,7 +54,7 @@
 10.100.0.0/16  us-west-2       workload  -                            0           100  64523 64520 64512 65000  -
 10.100.0.0/16  -               -             transit-gateway-route-table  0           100  64513 65000              -
 10.200.0.0/16  us-east-1       workload  -                            0           100  64522 64514 65001        -
-10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64523 64515 65001  -
+10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64522 64514 65001  -
 10.200.0.0/16  us-west-2       workload  -                            0           100  64523 64515 65001        -
 ===== RIB  SEGMENT=workload  EDGE=us-east-1 =====
 PREFIX         EDGE            SEG           TYPE                         LOCAL-PREF  MED  AS-PATH                  COMMUNITY
@@ -82,8 +82,6 @@
 10.100.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64512 65000        -
 10.100.0.0/16  us-west-2       workload  -                            0           100  64523 64520 64512 65000  -
 10.200.0.0/16  -               -             transit-gateway-route-table  0           100  64514 65001              -
-10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64523 64515 65001  -
-10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64523 64515 65001  -
 10.200.0.0/16  us-west-2       workload  -                            0           100  64523 64515 65001        -
 ===== RIB  SEGMENT=workload  EDGE=us-west-2 =====
 PREFIX         EDGE            SEG           TYPE                         LOCAL-PREF  MED  AS-PATH                  COMMUNITY
@@ -111,4 +109,6 @@
 10.100.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64513 65000        -
 10.100.0.0/16  us-east-1       workload  -                            0           100  64522 64520 64512 65000  -
 10.200.0.0/16  -               -             transit-gateway-route-table  0           100  64515 65001              -
+10.200.0.0/16  ap-northeast-1  workload  -                            0           100  64520 64522 64514 65001  -
+10.200.0.0/16  ap-northeast-3  workload  -                            0           100  64521 64522 64514 65001  -
 10.200.0.0/16  us-east-1       workload  -                            0           100  64522 64514 65001        -
\ No newline at end of file

まず、東京/大阪リージョンCNEの10.200.0.0/16のネクストホップが大阪/東京リージョンCNEになっているパスについて、AS_PATHが64515から64514に変わっていますね。いずれも10.200.0.0/16へのベストパスがバージニア北部CNEを経由するパスとなったことに起因しているものです。

また、バージニア北部リージョンCNEにて、10.200.0.0/16のネクストホップが東京/大阪リージョンCNEになっているパスが削除されています。これは以前は東京/大阪リージョンCNEの10.200.0.0/16へのネクストホップがバージニア北部CNEであることが決定したことにより、広告されてくるルートのAS_PATHにはバージニア北部CNEが自身のASNである64514が含まれるようになったためです。自ASNが含まれているため、ループにならないようにルートを破棄しています。

関連して、オレゴンリージョンCNEにて、10.200.0.0/16のネクストホップが東京/大阪リージョンCNEになっています。こちらはAS_PATH内にオレゴンリージョンCNEのASNを含まないため、ルートを受け取るようになりました。

この時のオンプレミスルーターのBGP情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-jp-router.log

10.2.0.0/1610.3.0.0/1610.12.0.0/1610.13.0.0/1610.200.0.0/16とCloud WANを介して接続しているネットワークとの経路について、AS_PATH長がそれぞれ4つとも同じです。

オンプレミスルーター側でもAS_PATH Prependをして経路制御をすると、先ほど確認したFIBやRIBの結果が変動してしまうので、今回はLocal Preferenceを設定して、オンプレ → AWSのルートを明示的に指定をします。東京オンプレミスルーターでは東京TGWを、バージニア北部オンプレミスルーターではバージニア北部TGWを優先させます。

具体的には東京オンプレミスルーターなら大阪、バージニア北部オンプレミスルーターならオレゴンリージョンのネットワークへのルートを除いて、Local Preferenceで200をセットします。

東京オンプレミスルーター
$ hostname -i
10.100.0.105

$ sudo ip netns exec vrf1 vtysh <<'EOF'
configure terminal
ip prefix-list SECONDARY_OWN_RESOURCES seq 5 permit 10.1.0.0/16
ip prefix-list SECONDARY_OWN_RESOURCES seq 10 permit 10.11.0.0/16
route-map PREFER_PRIMARY_IN permit 10
 match ip address prefix-list SECONDARY_OWN_RESOURCES
exit
route-map PREFER_PRIMARY_IN permit 20
 set local-preference 200
exit
router bgp 65000 vrf vrf1
 address-family ipv4 unicast
  neighbor 169.254.10.1 route-map PREFER_PRIMARY_IN in
  neighbor 169.254.10.5 route-map PREFER_PRIMARY_IN in
 exit-address-family
exit
end
clear bgp vrf vrf1 * soft in
write memory
EOF

Hello, this is FRRouting (version 10.4.1).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

ip-10-100-0-105.ap-northeast-1.compute.internal# configure terminal
ip-10-100-0-105.ap-northeast-1.compute.internal(config)# ip prefix-list SECONDARY_OWN_RESOURCES seq 5 permit 10.1.0.0/16
ip-10-100-0-105.ap-northeast-1.compute.internal(config)# ip prefix-list SECONDARY_OWN_RESOURCES seq 10 permit 10.11.0.0/16
ip-10-100-0-105.ap-northeast-1.compute.internal(config)# route-map PREFER_PRIMARY_IN permit 10
ip-10-100-0-105.ap-northeast-1.compute.internal(config-route-map)#  match ip address prefix-list SECONDARY_OWN_RESOURCES
ip-10-100-0-105.ap-northeast-1.compute.internal(config-route-map)# exit
ip-10-100-0-105.ap-northeast-1.compute.internal(config)# route-map PREFER_PRIMARY_IN permit 20
ip-10-100-0-105.ap-northeast-1.compute.internal(config-route-map)#  set local-preference 200
ip-10-100-0-105.ap-northeast-1.compute.internal(config-route-map)# exit
ip-10-100-0-105.ap-northeast-1.compute.internal(config)# router bgp 65000 vrf vrf1
ip-10-100-0-105.ap-northeast-1.compute.internal(config-router)#  address-family ipv4 unicast
ip-10-100-0-105.ap-northeast-1.compute.internal(config-router-af)#   neighbor 169.254.10.1 route-map PREFER_PRIMARY_IN in
ip-10-100-0-105.ap-northeast-1.compute.internal(config-router-af)#   neighbor 169.254.10.5 route-map PREFER_PRIMARY_IN in
ip-10-100-0-105.ap-northeast-1.compute.internal(config-router-af)#  exit-address-family
ip-10-100-0-105.ap-northeast-1.compute.internal(config-router)# exit
ip-10-100-0-105.ap-northeast-1.compute.internal(config)# end
ip-10-100-0-105.ap-northeast-1.compute.internal# clear bgp vrf vrf1 * soft in
ip-10-100-0-105.ap-northeast-1.compute.internal# write memory
Note: this version of vtysh never writes vtysh.conf
Building Configuration...
Integrated configuration saved to /etc/frr/frr.conf
[OK]
ip-10-100-0-105.ap-northeast-1.compute.internal#
バージニア北部オンプレミスルーター
$ hostname -i
10.200.0.79

$ sudo ip netns exec vrf1 vtysh <<'EOF'
configure terminal
ip prefix-list SECONDARY_OWN_RESOURCES seq 5 permit 10.3.0.0/16
ip prefix-list SECONDARY_OWN_RESOURCES seq 10 permit 10.13.0.0/16
route-map PREFER_PRIMARY_IN permit 10
 match ip address prefix-list SECONDARY_OWN_RESOURCES
exit
route-map PREFER_PRIMARY_IN permit 20
 set local-preference 200
exit
router bgp 65001 vrf vrf1
 address-family ipv4 unicast
  neighbor 169.254.30.1 route-map PREFER_PRIMARY_IN in
  neighbor 169.254.30.5 route-map PREFER_PRIMARY_IN in
 exit-address-family
exit
end
clear bgp vrf vrf1 * soft in
write memory
EOF

Hello, this is FRRouting (version 10.4.1).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

ip-10-200-0-79.ec2.internal# configure terminal
ip-10-200-0-79.ec2.internal(config)# ip prefix-list SECONDARY_OWN_RESOURCES seq 5 permit 10.3.0.0/16
ip-10-200-0-79.ec2.internal(config)# ip prefix-list SECONDARY_OWN_RESOURCES seq 10 permit 10.13.0.0/16
ip-10-200-0-79.ec2.internal(config)# route-map PREFER_PRIMARY_IN permit 10
ip-10-200-0-79.ec2.internal(config-route-map)#  match ip address prefix-list SECONDARY_OWN_RESOURCES
ip-10-200-0-79.ec2.internal(config-route-map)# exit
ip-10-200-0-79.ec2.internal(config)# route-map PREFER_PRIMARY_IN permit 20
ip-10-200-0-79.ec2.internal(config-route-map)#  set local-preference 200
ip-10-200-0-79.ec2.internal(config-route-map)# exit
ip-10-200-0-79.ec2.internal(config)# router bgp 65001 vrf vrf1
ip-10-200-0-79.ec2.internal(config-router)#  address-family ipv4 unicast
ip-10-200-0-79.ec2.internal(config-router-af)#   neighbor 169.254.30.1 route-map PREFER_PRIMARY_IN in
ip-10-200-0-79.ec2.internal(config-router-af)#   neighbor 169.254.30.5 route-map PREFER_PRIMARY_IN in
ip-10-200-0-79.ec2.internal(config-router-af)#  exit-address-family
ip-10-200-0-79.ec2.internal(config-router)# exit
ip-10-200-0-79.ec2.internal(config)# end
ip-10-200-0-79.ec2.internal# clear bgp vrf vrf1 * soft in
ip-10-200-0-79.ec2.internal# write memory
Note: this version of vtysh never writes vtysh.conf
Building Configuration...
Integrated configuration saved to /etc/frr/frr.conf
[OK]
ip-10-200-0-79.ec2.internal#

この状態の各オンプレミスルーターのBGP情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-jp-router.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-us-router.log

意図した通りにLocal Preferenceが設定され、ベストパスと判定されていますね。

疎通確認

先ほどと同様に疎通確認をします。

バージニア北部リージョンのオンプレミス相当VPCと東京リージョンTGWに接続しているVPC間の通信
$ hostname -i
10.200.1.82

$ ping -c 4 10.10.0.154
PING 10.10.0.154 (10.10.0.154) 56(84) bytes of data.
64 bytes from 10.10.0.154: icmp_seq=1 ttl=121 time=158 ms
64 bytes from 10.10.0.154: icmp_seq=2 ttl=121 time=152 ms
64 bytes from 10.10.0.154: icmp_seq=3 ttl=121 time=152 ms
64 bytes from 10.10.0.154: icmp_seq=4 ttl=121 time=152 ms

--- 10.10.0.154 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 151.892/153.589/158.111/2.614 ms
バージニア北部リージョンのオンプレミス相当VPCと大阪リージョンTGWに接続しているVPC間の通信
$ ping -c 4 10.11.0.131
PING 10.11.0.131 (10.11.0.131) 56(84) bytes of data.
64 bytes from 10.11.0.131: icmp_seq=1 ttl=121 time=164 ms
64 bytes from 10.11.0.131: icmp_seq=2 ttl=121 time=162 ms
64 bytes from 10.11.0.131: icmp_seq=3 ttl=121 time=162 ms
64 bytes from 10.11.0.131: icmp_seq=4 ttl=121 time=162 ms

--- 10.11.0.131 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 161.502/162.224/164.208/1.147 ms

非対称ルーティングだったものについて、変更後も問題なく通信できました。

また、その他のシナリオについても問題なく疎通できました。

TGW Flow Logsの確認

再度TGW Flow Logsを確認しましょう。

ダッシュボードでは以下のとおりです。

4.Routing Policy2およびLP設定後のダッシュボード.png

再度以下のように色付けをしてみました。

5.Routing Policy2およびLP設定後のダッシュボード_枠設定.png

対象ルーティングとなったことで、いずれの通信も2つのTGWのみを通るようになりました。

Cloud WANとバージニア北部TGWとのアタッチメントの削除

せっかくなので、一部が通信断となった場合にルート情報が更新されることを確認します。

今回は、Cloud WANとバージニア北部TGWとのアタッチメントの削除をします。

6.1.TGWアタッチメントの削除.png
7.attachment-0d2b2fa70cf403b93 を削除しますか.png

この時の各ルート情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-fib.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-rib.log

この状態の各オンプレミスルーターのBGP情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-us-router.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-jp-router.log

バージニア北部TGWに直接関連付けされている10.12.0.0/16のパスは無くなりましたが、バージニア北部CNEから10.200.0.0/16のネクストホップだったルートについて、ネクストホップがオレゴンリージョンのCNEになりましたね。うまく迂回できそうです。

一方で、東京リージョンや大阪リージョンのCNEから10.200.0.0/16へのネクストホップは変わらずバージニア北部リージョンのCNEとなってしまっています。バージニア北部リージョンのCNEにルーティングしたとしても10.200.0.0/16に到達するためには、オレゴンリージョンのTGWを介す必要があるため、本来であればオレゴンリージョンのCNEにルーティングした方が経路的には最適です。

これはassociate-routing-policyでRouting Policyを適用する対象を送信がオレゴンリージョンで受信が東京/大阪リージョン、送信が大阪リージョンで受信がバージニア北部/オレゴンリージョンの場合にのみにしてしまっているがためです。

こちらの適用条件では最短経路にのみAS_PATH Prependが行われてしまいます。その結果、BGPパスアトリビュートでは優劣が無くなり、今回のように迂回するような経路を選択してしまうことがあります。

architecture-associate-routing-policy-insufficient.drawio.png

architecture-associate-routing-policy-insufficient.drawio.png

回避するためには、大阪CNE→東京CNE、オレゴンCNE→バージニア北部CNEのように「非優先リージョンから優先リージョンに直接広告する」組み合わせについてもRouting Policyを適用するに、associate-routing-policyを設定することです。これにより、優先リージョンのCNEが非優先リージョンのCNEから経路を受信したにもAS_PATH Prependが適用され、再広告時にも引き継がれます。

今回の例だと、東京リージョンや大阪リージョンのCNEから10.200.0.0/16へのネクストホップは変わらずバージニア北部リージョンのCNEとなっていましたが、こちらの経路についてもAS_PATH Prependをすることによって、オレゴンリージョンのCNEがネクストホップとなります。

architecture-best-path-selection-after-adding-associate-routing-policy.drawio.png

実際にこのような環境を運用する場合は、各グループに優先リージョンCNE 1、非優先リージョンCNE 1の構成のオンプレミスネットワークのグループ数をGとすると、全リージョン数はN = 2G、非優先CNEの数もGになり、必要なassociate-routing-policyの数を次の式で求めることができます。

associate-routing-policy数 = 非優先CNEリージョンの数 × (全リージョン数  1) = G × (2G 1)

オンプレミスグループ数ごとの例は以下のとおりです。

オンプレミスグループ数 全リージョン数 非優先CNEリージョン数 associate-routing-policy 数
2 (今回の検証環境) 4 2 6
3 6 3 15
4 8 4 28
5 10 5 45

例えば、ヨーロッパグループとして、優先リージョンをアイルランド、非優先リージョンをフランクフルトリージョンとした場合のassociate-routing-policyの組み合わせは以下のとおりです。

受信 CNE (edge) \ 送信 CNE (peer) apne1 apne3 use1 usw2 euw1 euc1
apne1
apne3
use1
usw2
euw1
euc1

Cloud WANとバージニア北部TGWとのアタッチメントの再作成

Cloud WANとバージニア北部TGWとのアタッチメントの再作成をして、元の経路に戻るかどうかも確認します。

アタッチメント再作成後の各ルート情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-restore-fib.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-restore-rib.log

この状態の各オンプレミスルーターのBGP情報は以下のとおりです。

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-restore-jp-router.log

https://github.com/non-97/aws-cdk-cloud-wan-multi-region-tgw-vpn/blob/main/evidence/20260813/policy2-lp-use1-tgw-detach-restore-us-router.log

元に戻りましたね。

Routing Policyを用いてトラフィックをコントロールしよう

AWS Cloud WANとオンプレミスとが複数経路で接続されている場合に非対称ルーティングを防ぐためにはRouting Policyで制御をしてみました。

オンプレミスルーターのコントロールにハードルがある場合に出番がありそうですね。

BGPの気持ちになる必要はありますが、Routing Policyを用いることによってきめ細かいトラフィックコントロールができます。

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事