[アップデート] Regional NAT GatewayがAWS Transit Gatewayとの連携をサポートしたのでインターネットへのアウトバウンド通信集約をやってみた

[アップデート] Regional NAT GatewayがAWS Transit Gatewayとの連携をサポートしたのでインターネットへのアウトバウンド通信集約をやってみた

Network Firewall Proxy以外ではRegional NAT Gatewayを使用することになりそう
2026.05.08

Regional NAT GatewayとTransit Gatewayを用いて複数VPCのインターネットアウトバウンド通信の集約をしたい

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

皆さんはRegional NAT GatewayとTransit Gatewayを用いて複数VPCのインターネットアウトバウンド通信の集約をしたいなと思ったことはありますか? 私はあります。

以下記事で紹介したとおり、Regional NAT Gateway GA当時ではTransit Gatewayとを組み合わせて複数VPCのインターネットアウトバウンド通信の集約をすることは、可用性的にもレイテンシー的にも、運用負荷的にもオススメできるものではありませんでした。

https://dev.classmethod.jp/articles/regional-nat-gateway-centralized-egress/

この原因はRegional NAT Gateway route tableにおいてTransit Gatewayをターゲットとするルートを設定できなかったためです。

それがなんと、しれっとサポートされるようになったのではありませんか。

https://x.com/yukihirokikuchi/status/2052549027624042649

リージョン NAT ゲートウェイは、リージョン NAT ゲートウェイルートテーブルで有効なルートとして AWS Transit Gateway をサポートします。リージョン NAT ゲートウェイはプライベート NAT をサポートしていません。プライベート NAT が必要な場合は、代わりにゾーン NAT ゲートウェイを使用してください。

自動マルチ AZ 拡張用のリージョン NAT ゲートウェイ - Amazon Virtual Private Cloud

これは嬉しいですね。

Regional NAT Gateway採用を諦めるシナリオが減りました。

Internet Archiveで該当AWS公式ドキュメントを確認したところ、2026/3/14時点ではこちらの文言がなかったところ、2026/4/12時点のアーカイブではこちらの文言が生えてきたので、その間にサポートされたのかと想像しています。

実際に試してみます。

いきなりまとめ

  • インターネットへのアウトバウンド通信集約でRegional NAT GatewayとTransit Gatewayの組み合わせを採用できるようになった
  • Transit GatewayはVPCで使用している全AZに関連付けよう

やってみた

検証環境

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

検証環境構成図.png

Reginal NAT GatewayやTransit Gatewayの作成は完了しており、Regional NAT Gateway route table以外のルートテーブルの設定も完了している状態です。

ちなみにRegional NAT Gatewayは以下のようにAWS CLIで作成しました。EIPは事前に用意していたものを手動で割り当てる形です。

> aws ec2 create-nat-gateway \
    --availability-mode regional \
    --vpc-id vpc-03e01ad6b5702f616 \
    --availability-zone-addresses '[
      {"AvailabilityZone":"us-east-1a","AllocationIds":["eipalloc-068a38024d6b72052"]},
      {"AvailabilityZone":"us-east-1b","AllocationIds":["eipalloc-099df8796179fc8cf"]}
    ]'
{
    "ClientToken": "5173d9ed-db10-49b5-b366-8746c1d9127d",
    "NatGateway": {
        "CreateTime": "2026-05-08T05:51:57+00:00",
        "NatGatewayAddresses": [
            {
                "AllocationId": "eipalloc-099df8796179fc8cf",
                "Status": "associating",
                "AvailabilityZone": "us-east-1b",
                "AvailabilityZoneId": "use1-az1"
            },
            {
                "AllocationId": "eipalloc-068a38024d6b72052",
                "Status": "associating",
                "AvailabilityZone": "us-east-1a",
                "AvailabilityZoneId": "use1-az6"
            }
        ],
        "NatGatewayId": "nat-1b3241d29dde921a3",
        "State": "pending",
        "VpcId": "vpc-03e01ad6b5702f616",
        "ConnectivityType": "public",
        "AvailabilityMode": "regional",
        "AutoScalingIps": "disabled",
        "AutoProvisionZones": "disabled"
    }
}

> aws ec2 describe-nat-gateways --nat-gateway-ids nat-1b3241d29dde921a3
{
    "NatGateways": [
        {
            "CreateTime": "2026-05-08T05:51:57+00:00",
            "NatGatewayAddresses": [
                {
                    "AllocationId": "eipalloc-099df8796179fc8cf",
                    "PublicIp": "34.206.250.38",
                    "AssociationId": "eipassoc-0c44398ce197dc5a6",
                    "Status": "succeeded",
                    "AvailabilityZone": "us-east-1b",
                    "AvailabilityZoneId": "use1-az1"
                },
                {
                    "AllocationId": "eipalloc-068a38024d6b72052",
                    "PublicIp": "35.174.131.105",
                    "AssociationId": "eipassoc-0c53b93329e3c7914",
                    "Status": "succeeded",
                    "AvailabilityZone": "us-east-1a",
                    "AvailabilityZoneId": "use1-az6"
                }
            ],
            "NatGatewayId": "nat-1b3241d29dde921a3",
            "State": "available",
            "VpcId": "vpc-03e01ad6b5702f616",
            "Tags": [],
            "ConnectivityType": "public",
            "AvailabilityMode": "regional",
            "AutoScalingIps": "disabled",
            "AutoProvisionZones": "disabled",
            "RouteTableId": "rtb-0fc072322246c649c"
        }
    ]
}

Regional NAT Gateway route tableでターゲットをTransit Gatewayに設定する

それではRegional NAT Gateway route tableにおいてTransit Gatewayをターゲットとするルートを設定してみましょう。

AWSマネジメントコンソールから確認すると、確かに設定できそうです。

1.Regional NAT Gateway route tableでTransit Gatewayをターゲットにするルートの追加.png

このまま変更を保存をクリックすると、無事ルート追加が反映されました。

2.Regional NAT Gateway route tableでTransit Gatewayをターゲットにするルートの追加確認.png

動作確認

動作確認をします。Spoke VPC上の各AZのEC2インスタンスからhttp://checkip.amazonaws.comに対するcurlを叩きます。

us-east-1a
$ TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
$ curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone
us-east-1a

$ hostname -i
10.0.2.139

$ curl http://checkip.amazonaws.com
35.174.131.105

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 35.174.131.105
us-east-1b
$ TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
$ curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone
us-east-1b

$ hostname -i
10.0.6.186

$ curl http://checkip.amazonaws.com
34.206.250.38

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 34.206.250.38
us-east-1c
$ TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
$ curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone
us-east-1c

$ hostname -i
10.0.10.12

$ curl http://checkip.amazonaws.com
34.206.250.38

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
     55 34.206.250.38
     45 35.174.131.105

us-east-1aとus-east-1bについては常に同じAZのEIPからインターネットに抜けていることが分かりますね。

図示すると以下のとおりです。

us-east-1aとus-east-1bの通信.png

これはTransit Gatewayを介したVPC間の通信は原則送信元と同一AZのENIを経由して通信をするためです。

ルーティング動作1.png

抜粋 : AWS Black Belt Online Seminar AWS Transit Gateway deep dive P.21

一方、us-east-1cについてはEgress VPCとTransit Gatewayの関連付けでus-east-1cのENIが存在しないがために、us-east-1aとus-east-1cにラウンドロビンされていることがわかります。

図示すると以下のとおりです。

us-east-1cの通信.png

これはTransit Gatewayを介したVPC間の通信において、送信元と同一AZのENIが存在しない場合は、いずれかのENIを経由して通信をする性質があるためです。

ルーティング動作2.png

抜粋 : AWS Black Belt Online Seminar AWS Transit Gateway deep dive P.22

Egress VPCの特定AZのTransit Gateway attachmentの関連付けを解除した場合

続いて、Egress VPCにおいてTransit Gatewayのus-east-1bとの関連付けを解除した場合の通信を試します。

図示すると以下のとおりです。

Egress VPCの特定AZのTransit Gateway attachmentの関連付けを解除した場合.png

以下のように、Egress VPCのTransit Gateway attachmentでus-east-1bの関連付けを解除しました。

3.tgw-attach-0a41c7fec51b0b7ed.png

この状態で動作確認をしてみます。

us-east-1a
$ hostname -i
10.0.2.139

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 35.174.131.105
us-east-1b
$ hostname -i
10.0.6.186

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 35.174.131.105
us-east-1c
$ hostname -i
10.0.10.12

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 35.174.131.105

はい、全ての通信がus-east-1aのEIPから抜けていくようにようになりました。Egress VPCのTransit Gateway attachmentの特定AZが不調であった場合でも通信を継続できそうです。

Reginal NAT Gateway特定AZのEIPの関連付けを解除した場合

最後にRegional NAT Gatewayでus-east-1aのEIPの関連付けを解除した場合の挙動を確認します。

図示すると以下のとおりです。

Reginal NAT Gateway特定AZのEIPの関連付けを解除した場合.png

> aws ec2 disassociate-nat-gateway-address \
    --nat-gateway-id nat-1b3241d29dde921a3 \
    --association-ids eipassoc-0c53b93329e3c7914
{
    "NatGatewayId": "nat-1b3241d29dde921a3",
    "NatGatewayAddresses": [
        {
            "AllocationId": "eipalloc-068a38024d6b72052",
            "PublicIp": "35.174.131.105",
            "AssociationId": "eipassoc-0c53b93329e3c7914",
            "Status": "disassociating",
            "AvailabilityZone": "us-east-1a",
            "AvailabilityZoneId": "use1-az6"
        }
    ]
}

> aws ec2 describe-nat-gateways --nat-gateway-ids nat-1b3241d29dde921a3
{
    "NatGateways": [
        {
            "CreateTime": "2026-05-08T05:51:57+00:00",
            "NatGatewayAddresses": [
                {
                    "AllocationId": "eipalloc-099df8796179fc8cf",
                    "PublicIp": "34.206.250.38",
                    "AssociationId": "eipassoc-0c44398ce197dc5a6",
                    "Status": "succeeded",
                    "AvailabilityZone": "us-east-1b",
                    "AvailabilityZoneId": "use1-az1"
                },
                {
                    "AllocationId": "eipalloc-068a38024d6b72052",
                    "PublicIp": "35.174.131.105",
                    "AssociationId": "eipassoc-0c53b93329e3c7914",
                    "Status": "disassociating",
                    "AvailabilityZone": "us-east-1a",
                    "AvailabilityZoneId": "use1-az6"
                }
            ],
            "NatGatewayId": "nat-1b3241d29dde921a3",
            "State": "available",
            "VpcId": "vpc-03e01ad6b5702f616",
            "Tags": [],
            "ConnectivityType": "public",
            "AvailabilityMode": "regional",
            "AutoScalingIps": "disabled",
            "AutoProvisionZones": "disabled",
            "RouteTableId": "rtb-0fc072322246c649c"
        }
    ]
}

> aws ec2 describe-nat-gateways --nat-gateway-ids nat-1b3241d29dde921a3
{
    "NatGateways": [
        {
            "CreateTime": "2026-05-08T05:51:57+00:00",
            "NatGatewayAddresses": [
                {
                    "AllocationId": "eipalloc-099df8796179fc8cf",
                    "PublicIp": "34.206.250.38",
                    "AssociationId": "eipassoc-0c44398ce197dc5a6",
                    "Status": "succeeded",
                    "AvailabilityZone": "us-east-1b",
                    "AvailabilityZoneId": "use1-az1"
                }
            ],
            "NatGatewayId": "nat-1b3241d29dde921a3",
            "State": "available",
            "VpcId": "vpc-03e01ad6b5702f616",
            "Tags": [],
            "ConnectivityType": "public",
            "AvailabilityMode": "regional",
            "AutoScalingIps": "disabled",
            "AutoProvisionZones": "disabled",
            "RouteTableId": "rtb-0fc072322246c649c"
        }
    ]
}

この状態で動作確認をします。

us-east-1a
$ hostname -i
10.0.2.139

$ curl -v -m 5 http://checkip.amazonaws.com
* Host checkip.amazonaws.com:80 was resolved.
* IPv6: (none)
* IPv4: 18.214.81.101, 107.22.174.34, 98.88.227.245, 34.198.9.7, 54.161.5.8, 3.208.250.44, 34.226.231.9, 18.235.123.226
*   Trying 18.214.81.101:80...
*   Trying 107.22.174.34:80...
*   Trying 98.88.227.245:80...
*   Trying 34.198.9.7:80...
*   Trying 54.161.5.8:80...
*   Trying 3.208.250.44:80...
*   Trying 34.226.231.9:80...
*   Trying 18.235.123.226:80...
* Connection timed out after 5000 milliseconds
* closing connection #0
curl: (28) Connection timed out after 5000 milliseconds
us-east-1b
$ hostname -i
10.0.6.186

$ curl -v -m 5 http://checkip.amazonaws.com
* Host checkip.amazonaws.com:80 was resolved.
* IPv6: (none)
* IPv4: 44.219.78.34, 98.88.227.245, 34.234.160.105, 3.217.138.21, 34.226.231.9, 54.161.5.8, 34.198.9.7, 3.208.250.44
*   Trying 44.219.78.34:80...
*   Trying 98.88.227.245:80...
*   Trying 34.234.160.105:80...
*   Trying 3.217.138.21:80...
*   Trying 34.226.231.9:80...
*   Trying 54.161.5.8:80...
*   Trying 34.198.9.7:80...
*   Trying 3.208.250.44:80...
* Connection timed out after 5001 milliseconds
* closing connection #0
curl: (28) Connection timed out after 5001 milliseconds
us-east-1c
$ hostname -i
10.0.10.12

$ curl -v -m 5 http://checkip.amazonaws.com
* Host checkip.amazonaws.com:80 was resolved.
* IPv6: (none)
* IPv4: 98.88.227.245, 3.208.250.44, 54.161.5.8, 18.214.81.101, 32.193.185.179, 3.217.138.21, 34.226.231.9, 18.235.123.226
*   Trying 98.88.227.245:80...
*   Trying 3.208.250.44:80...
*   Trying 54.161.5.8:80...
*   Trying 18.214.81.101:80...
*   Trying 32.193.185.179:80...
*   Trying 3.217.138.21:80...
*   Trying 34.226.231.9:80...
*   Trying 18.235.123.226:80...
* Connection timed out after 5001 milliseconds
* closing connection #0
curl: (28) Connection timed out after 5001 milliseconds

はい、いずれも通信できなくなりました。

これはReginal NAT GatewayのEIPと同一AZにTransit Gateway attachmentのENIがないため発生しています。Transit GatewayはTransit Gateway attachmentが関連づけられている同一のAZのリソースのみ通信できるためです。

Transit Gateway アタッチメントが存在するアベイラビリティーゾーンにあるリソースのみ、Transit Gateway に到達できます。

AWS Transit Gateway の仕組み - Amazon VPC

図示すると以下のとおりです。

Reginal NAT Gateway特定AZのEIPの関連付けを解除した場合_通信フロー.png

ということで、Transit Gateway attachmentを関連づけていないAZに対してRegional NAT Gatewayを関連づけてしまうと、このように通信できない事象が発生してしまいます。Transit Gateway attachmentを関連づけるAZ数によって課金額は特に変わらないので、VPCで使用している全AZに関連付けを行いましょう。

ちなみに、Egress VPCのTransit Gateway attachmentでus-east-1bも関連付けを行うと再度通信できるようになります。

us-east-1a
$ hostname -i
10.0.2.139

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 34.206.250.38
us-east-1b
$ hostname -i
10.0.6.186

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 34.206.250.38
us-east-1c
$ hostname -i
10.0.10.12

$ for i in $(seq 100); do curl -s http://checkip.amazonaws.com; done | sort | uniq -c | sort -rn
    100 34.206.250.38

障害の度合いに大きくよりますが、Regional NAT Gatewayで特定AZが不調な場合であっても上手く通信できそうです。

Network Firewall Proxy以外ではRegional NAT Gatewayを使用することになりそう

Regional NAT GatewayがAWS Transit Gatewayとの連携をサポートしたアップデートを紹介しました。

これによりRegional NAT Gateway採用のハードルが一つ減った形になります。

個人的にはNetwork Firewall Proxy以外ではRegional NAT Gatewayを使用することになる認識です。

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

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

この記事をシェアする

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

関連記事