リージョナルNAT Gatewayを複数VPCのインターネットアウトバウンド集約に使用することは現状オススメしない件

リージョナルNAT Gatewayを複数VPCのインターネットアウトバウンド集約に使用することは現状オススメしない件

大雑把な設定だと可用性もレイテンシーも料金もZonal NAT Gatewayよりも悪化する可能性があるため個人的にはオススメしない
2025.11.22

結局リージョナルNAT GatewayとTransit Gatewayを用いて複数VPCのインターネットアウトバウンド集約を行うことはできるのか気になる

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

皆さんは結局リージョナルNAT GatewayとTransit Gatewayを用いて複数VPCのインターネットアウトバウンド集約を行うことはできるのか気になったことはありますか? 私はあります。

以下記事で軽く検証をしたところ対応は出来なさそうでした。

https://dev.classmethod.jp/articles/aws-nat-gateway-regional-availability/

具体的には、戻りの通信をTransit Gatewayにルーティングをするために、リージョナルNAT GatewayのエッジルートテーブルにTransit Gatewayをターゲットにしたルートを作成しようとしたところ、エラーになってしまいました。

加えて、リージョナルNAT GatewayがGAされたタイミングでAWS Blogsに投稿されていた記事に記載されていた、以下アウトバウンド通信の集約に関する記述が現在は削除されてしまっています。

Centralized egress

You can deploy a centralized egress VPC with a NAT gateway in regional availability mode that serves multiple application VPCs. Application VPCs connect to the egress VPC via AWS Transit Gateway or AWS Cloud WAN. Outbound traffic flows through the transit gateway to the egress VPC, where the NAT gateway performs network address translation using Elastic IP addresses from your IPAM pool.

Build scalable IPv4 addressing with AWS NAT gateway in regional availability mode, Amazon VPC IPAM policies and Prefix Lists | Networking & Content Delivery

本当にリージョナルNAT Gatewayでは複数VPCのインターネットのアウトバウンド集約に使用できないのでしょうか。

改めて検証をします。

いきなりまとめ

  • リージョナルNAT Gatewayを複数VPCのインターネットアウトバウンド集約できる
    • Transit GatewayにルーティングするためにTransit Gateway attachmentのENIを指定することで実現
  • ただし、以下理由から現状オススメしない
    • ターゲットをTransit Gateway attachmentの一つのAZのIDのみ設定するような大雑把な設定だと、可用性もレイテンシーも料金もZonal NAT Gatewayを用いる場合よりも悪化する可能性があるため
    • AZ毎にCIDRブロックを把握した上できめ細かくルートテーブルを管理するのは運用負荷が高いため
  • リージョナルNAT GatewayのエッジルートテーブルのルートのターゲットとしてTransit Gatewayを指定できるようになるのを待とう
  • リージョナルNAT Gatewayに対してはVPC Flow Logsは設定できない

やってみた

検証環境

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

検証環境.png

以前の検証のものを再利用します。

リージョナルNAT GatewayやTransit Gatewayの作成は完了しており、リージョナルNAT Gatewayのエッジルートテーブル以外のルートテーブルの設定も完了している状態です。

リージョナルNAT Gatewayのエッジルートテーブルのルート追加

では、リージョナルNAT Gatewayのエッジルートテーブルのルート追加を行います。

リージョナルNAT Gatewayのエッジルートテーブルのルートを追加しようとします。

1.リージョナルNAT Gatewayのエッジルートテーブルのターゲットで指定できるリソースタイプ.png

はい、GA当日は指定できたTransit Gatewayが指定できなくなっていました。

指定できるリソースタイプは以下3種類です。

  • Internet Gateway
  • ENI
  • Gateway Load Balancerのエンドポイント

GAされて2日でマネジメントコンソール上で修正が入ったようです。

Transit Gatewayにルーティングするためには、Transit Gateway attachmentのENIを指定するしかありません。

しかし、こちらのENIがダウンした場合、全アウトバウンド通信の戻りの通信がTransit Gatewayにルーティングされなくなります。要するにSPOFになっています。

要するにSPOF.png

せっかくのリージョナルNAT Gatewayの魅力が半減します。Zonal NAT Gatewayの方がAZで分離されているため、1AZのTransit Gateway attachmentのENIがダウンしたとしても影響範囲は同一AZのラインのみとなります。

影響範囲は同一AZのラインのみ.png

強いて緩和策を挙げるとするならば、アウトバウンド集約元の全VPCの全サブネットのCIDRブロックをAZごとに整理し、整理したサブネットCIDRブロックごとにサブネットと同一AZのTransit Gateway attachmentのENIを指定する方法があります。

緩和策.png

サブネット数が多い場合、プレフィックスリストを使ったとしても非常に運用負荷が高い作業でしょう。個人的には全くお勧めしません。

今回はTransit Gateway attachmentのENIを指定するしかありません。

us-east-1aのTransit Gateway attachmentのENIをターゲットに指定します。

3.rtb-045b599542015ddbfのルートを正常に更新しました.png

設定完了しました。

2.Transit Gateway attachmentのENIを指定.png

疎通確認

疎通確認を行います。

現在のリージョナルNAT Gatewayに関連づけられているElastic IPアドレスは以下のとおりです。

  • 50.16.195.34 : us-east-1a
  • 54.235.146.62 : us-east-1b

4.NAT GatewayのIPアドレス.png

us-east-1aのEC2インスタンスからcheckip.amazonaws.comへアクセスします。

$ 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

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

$ while true; do
  echo "$(date '+%Y/%m/%d %H:%M:%S') - $(curl -s --no-keepalive http://checkip.amazonaws.com)"
  sleep 1
done
2025/11/21 10:44:33 - 50.16.195.34
2025/11/21 10:44:34 - 50.16.195.34
2025/11/21 10:44:35 - 50.16.195.34
2025/11/21 10:44:36 - 50.16.195.34
2025/11/21 10:44:37 - 50.16.195.34
2025/11/21 10:44:38 - 50.16.195.34
2025/11/21 10:44:39 - 50.16.195.34
2025/11/21 10:44:40 - 50.16.195.34
2025/11/21 10:44:41 - 50.16.195.34
2025/11/21 10:44:42 - 50.16.195.34
2025/11/21 10:44:43 - 50.16.195.34
^C

us-east-1aのElastic IPアドレスが返ってきましたね。

続いて、us-east-1bのEC2インスタンスです。

$ 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

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

$ while true; do
  echo "$(date '+%Y/%m/%d %H:%M:%S') - $(curl -s --no-keepalive http://checkip.amazonaws.com)"
  sleep 1
done
2025/11/21 10:46:30 - 54.235.146.62
2025/11/21 10:46:31 - 54.235.146.62
2025/11/21 10:46:32 - 54.235.146.62
2025/11/21 10:46:33 - 54.235.146.62
2025/11/21 10:46:34 - 54.235.146.62
2025/11/21 10:46:35 - 54.235.146.62
2025/11/21 10:46:36 - 54.235.146.62
2025/11/21 10:46:37 - 54.235.146.62
2025/11/21 10:46:38 - 54.235.146.62
2025/11/21 10:46:39 - 54.235.146.62
2025/11/21 10:46:40 - 54.235.146.62
^C

us-east-1bのElastic IPアドレスが返ってきましたね。

続いて、us-east-1cのEC2インスタンスです。

$ 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

$ curl http://checkip.amazonaws.com -vm 5
* Host checkip.amazonaws.com:80 was resolved.
* IPv6: (none)
* IPv4: 52.203.49.206, 52.3.168.227, 23.20.249.94, 54.243.172.31, 35.174.118.36, 13.216.28.7, 3.217.8.166, 35.170.18.232
*   Trying 52.203.49.206:80...
* ipv4 connect timeout after 2500ms, move on!
*   Trying 52.3.168.227:80...
* ipv4 connect timeout after 1249ms, move on!
*   Trying 23.20.249.94:80...
* ipv4 connect timeout after 623ms, move on!
*   Trying 54.243.172.31:80...
* ipv4 connect timeout after 312ms, move on!
*   Trying 35.174.118.36:80...
* Connection timed out after 5002 milliseconds
* closing connection #0
curl: (28) Connection timed out after 5002 milliseconds

はい、疎通できませんでした。

この原因は送信元VPCのTransit Gateway attachmentにus-east-1cを関連づけていなかったためです。

送信元VPCおよびEgress VPCにus-east-1cのサブネットを追加し、Transit Gateway attachmentのENIの追加をします。

  • サブネットの追加
    12.big-ip-test-subnet-application-us-east-1c.png
    9.サブネットの追加.png
  • サブネットのルートテーブルの関連付け
    13.ルートテーブルの関連付け.png
    10.ルートテーブルの関連付け.png
  • Transit Gateway attachmentのサブネット追加
    14.BIG-IPのTransit Gateway attachmentのサブネット追加.png
    11.Transit Gateway attachmentのサブネット追加.png

現在の状態を図示すると以下のとおりです。

us-east-1cの attachment追加後.png

この状態で再度トライします。

$ while true; do
  echo "$(date '+%Y/%m/%d %H:%M:%S') - $(curl -s -m 5 --no-keepalive http://checkip.amazonaws.com)"
  sleep 1
done
2025/11/21 11:14:21 - 
2025/11/21 11:14:27 - 
2025/11/21 11:14:33 - 
2025/11/21 11:14:39 - 
2025/11/21 11:14:45 - 
2025/11/21 11:14:51 - 
2025/11/21 11:14:57 - 
2025/11/21 11:15:03 - 
2025/11/21 11:15:09 - 
2025/11/21 11:15:15 - 50.16.195.34
2025/11/21 11:15:16 - 50.16.195.34
2025/11/21 11:15:22 - 50.16.195.34
2025/11/21 11:15:25 - 50.16.195.34
2025/11/21 11:15:26 - 50.16.195.34
2025/11/21 11:15:27 - 50.16.195.34
2025/11/21 11:15:28 - 50.16.195.34
2025/11/21 11:15:29 - 50.16.195.34
2025/11/21 11:15:30 - 50.16.195.34
2025/11/21 11:15:31 - 50.16.195.34
2025/11/21 11:15:32 - 50.16.195.34
2025/11/21 11:15:33 - 50.16.195.34

通るようになりました。使用しているElastic IPアドレスはus-east-1aのものです。

この状態で、20:17:20にEgress VPCのus-east-1cのTransit GatewayのENIを削除します。

15.Egressのus-east-1cのサブネットのアタッチメントを削除.png

削除処理前から継続してアクセスを行います。ログは以下のとおりです。

2025/11/21 11:17:23 - 50.16.195.34
2025/11/21 11:17:24 - 50.16.195.34
2025/11/21 11:17:26 - 50.16.195.34
2025/11/21 11:17:27 - 50.16.195.34
2025/11/21 11:17:28 - 50.16.195.34
2025/11/21 11:17:29 - 50.16.195.34
2025/11/21 11:17:30 - 50.16.195.34
2025/11/21 11:17:31 - 50.16.195.34
2025/11/21 11:17:32 - 50.16.195.34
2025/11/21 11:17:33 - 50.16.195.34
2025/11/21 11:17:34 - 
2025/11/21 11:17:40 - 
2025/11/21 11:17:46 - 
2025/11/21 11:17:52 - 
2025/11/21 11:17:58 - 
2025/11/21 11:18:04 - 
2025/11/21 11:18:10 - 54.235.146.62
2025/11/21 11:18:15 - 50.16.195.34
2025/11/21 11:18:16 - 54.235.146.62
2025/11/21 11:18:17 - 50.16.195.34
2025/11/21 11:18:18 - 50.16.195.34
2025/11/21 11:18:19 - 50.16.195.34
2025/11/21 11:18:20 - 54.235.146.62
2025/11/21 11:18:22 - 54.235.146.62
2025/11/21 11:18:23 - 50.16.195.34
2025/11/21 11:18:24 - 50.16.195.34
2025/11/21 11:18:25 - 54.235.146.62
2025/11/21 11:18:26 - 54.235.146.62
2025/11/21 11:18:27 - 50.16.195.34
2025/11/21 11:18:28 - 50.16.195.34
2025/11/21 11:18:29 - 54.235.146.62
2025/11/21 11:18:30 - 54.235.146.62
2025/11/21 11:18:31 - 50.16.195.34

30秒ほどの段のあと、us-east-1aとus-east-1bのElastic IPアドレスをおおよそ交互に使用するようになりました。

こちらはTransit Gatewayの仕様です。以下で紹介されているように、送信先に同⼀AZのTransit Gateway attachmentのENIが存在しない場合は、いずれかのENIを経由して通信します。

16.送信先に同⼀ AZ が存在しない場合は、いずれかの ENI を経由して通信する.png

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

結論としては、リージョナルNAT GatewayのエッジルートテーブルのルートのターゲットにTransit Gatewayではなく、Transit Gateway attachmentのENIを指定することでインターネットのアウトバウンド通信を集約できることが分かりました。

疎通確認時のログを確認

実際の通信の様子を確認したいですね。

リージョナル NAT Gatewayは個別にVPC Flow Logsを設定できそうな雰囲気です。

17.リージョナルNAT GatewayのVPC Flow Logs.png

設定してみましょう。

6.リージョナルNAT GatewayのVPC Flow Logsの設定.png

ログに記録するフィールドは以下のとおりです。

${account-id} ${action} ${az-id} ${bytes} ${dstaddr} ${dstport} ${end} ${flow-direction} ${instance-id} ${interface-id} ${log-status} ${packets} ${pkt-dst-aws-service} ${pkt-dstaddr} ${pkt-src-aws-service} ${pkt-srcaddr} ${protocol} ${region} ${reject-reason} ${srcaddr} ${srcport} ${start} ${sublocation-id} ${sublocation-type} ${subnet-id} ${tcp-flags} ${traffic-path} ${type} ${version} ${vpc-id} ${resource-id}

いざ、作成をしようとすると、2 validation errors detected: Value '0' at 'rnatDescriptions.1.member.availabilityZoneMapping.1.member.maxDrainDurationSeconds' has an invalid format; Value '0' at 'rnatDescriptions.1.member.availabilityZoneMapping.2.member.maxDrainDurationSeconds' has an invalid formatとエラーになってしまいました。

7.フローログを作成できません.png

エラーメッセージから考えるに、リージョナルNAT GatewayのElastic IPアドレスの関連付けについてのメッセージであり、VPC Flow Logsの指定パラメーターに不具合があるといった代物ではありません。

時間を置いて再度リトライしても、出力先をCloudWatch LogsからS3バケットに変更しても、ログレコード形式をデフォルトのものに変更しても結果は変わりませんでした。

リージョナルNAT Gatewayに対してはVPC Flow Logsは設定できないと考えて良いでしょう。

Transit Gateway Flow Logsを見ましょう。

CREATE EXTERNAL TABLE `transit_gateway_flow_logs_partition_projection`(
  `version` int, 
  `resource_type` string, 
  `account_id` string, 
  `tgw_id` string, 
  `tgw_attachment_id` string, 
  `tgw_src_vpc_account_id` string, 
  `tgw_dst_vpc_account_id` string, 
  `tgw_src_vpc_id` string, 
  `tgw_dst_vpc_id` string, 
  `tgw_src_subnet_id` string, 
  `tgw_dst_subnet_id` string, 
  `tgw_src_eni` string, 
  `tgw_dst_eni` string, 
  `tgw_src_az_id` string, 
  `tgw_dst_az_id` string, 
  `tgw_pair_attachment_id` string, 
  `srcaddr` string, 
  `dstaddr` string, 
  `srcport` int, 
  `dstport` int, 
  `protocol` bigint, 
  `packets` bigint, 
  `bytes` bigint, 
  `start` bigint, 
  `end` bigint, 
  `log_status` string, 
  `type` string, 
  `packets_lost_no_route` bigint, 
  `packets_lost_blackhole` bigint, 
  `packets_lost_mtu_exceeded` bigint, 
  `packets_lost_ttl_expired` bigint, 
  `tcp_flags` int, 
  `region` string, 
  `flow_direction` string, 
  `pkt_src_aws_service` string, 
  `pkt_dst_aws_service` string
)
PARTITIONED BY (
  `datehour` string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
LOCATION
  's3://bucket-tgw-flow-logs-956004e0-b408-11ee-8ba7-0af1bc648567/AWSLogs/'
TBLPROPERTIES (
  'projection.enabled'='true',
  'has_encrypted_data'='true',
  "skip.header.line.count"="1",
  'projection.datehour.type'='date',
  'projection.datehour.interval'='1',
  'projection.datehour.interval.unit'='HOURS',
  'projection.datehour.range'='NOW-3DAYS,NOW',
  'projection.datehour.format'='yyyy/MM/dd/HH',
  'storage.location.template'='s3://bucket-tgw-flow-logs-956004e0-b408-11ee-8ba7-0af1bc648567/AWSLogs/<AWSアカウントID>/vpcflowlogs/us-east-1/${datehour}'
)

意図したフォーマットで記録されているかを確認します。

SELECT *
FROM
  transit_gateway_flow_logs_partition_projection
WHERE
  datehour='2025/11/21/11' and
  (srcaddr='10.0.10.11' or dstaddr='10.0.10.11') and
  (dstport=80 or srcport=80)

18.Athenaクエリの実行.png

良い感じに出力されました。

us-east-1cのEC2インスタンスからの通信について、戻りの通信で、送信元と送信先のTransit Gateway attachmentのENIのAZが異なるものを抽出します。

SELECT 
  tgw_src_eni,
  tgw_dst_eni,
  tgw_src_az_id,
  tgw_dst_az_id,
  srcaddr,
  dstaddr,
  protocol,
  "start",
  "end",
  log_status,
  packets_lost_no_route,
  packets_lost_blackhole, 
  tcp_flags,
  flow_direction
FROM
  transit_gateway_flow_logs_partition_projection
WHERE
  datehour='2025/11/21/11' and
  dstaddr='10.0.10.11' and
  srcport=80 and
  tgw_src_az_id != tgw_dst_az_id

結果は以下のとおりです。

# tgw_src_eni tgw_dst_eni tgw_src_az_id tgw_dst_az_id srcaddr dstaddr protocol start end log_status packets_lost_no_route packets_lost_blackhole tcp_flags flow_direction
1 eni-019a991b2815b9e49 eni-05639bab671d1ddb7 use1-az6 use1-az2 35.174.118.36 10.0.10.11 6 1763723898 1763723936 OK 0 0 27 ingress
2 eni-019a991b2815b9e49 eni-05639bab671d1ddb7 use1-az6 use1-az2 3.222.182.34 10.0.10.11 6 1763723898 1763723936 OK 0 0 27 ingress

2つだけでした。AZ IDとAZ名の関係性は以下のとおりです。

  • us-east-1a : use1-az6
  • us-east-1b : use1-az1
  • us-east-1c : use1-az2

1763723898はEgress VPCのTransit Gateway attachmentのus-east-1cのENIを削除したタイミングと近いので、このような事象が発生したのかもしれません。

また、以下クエリでTransit Gateway attachmentのus-east-1cのENIを削除が完了して20秒ほど経過した20:18:40以降で、送信元と送信先が同一AZの通信を確認します。

SELECT 
  tgw_src_eni,
  tgw_dst_eni,
  tgw_src_az_id,
  tgw_dst_az_id,
  srcaddr,
  dstaddr,
  protocol,
  "start",
  "end",
  log_status,
  packets_lost_no_route,
  packets_lost_blackhole, 
  tcp_flags,
  flow_direction
FROM
  transit_gateway_flow_logs_partition_projection
WHERE
  datehour='2025/11/21/11' and
  dstaddr='10.0.10.11' and
  srcport=80 and
  tgw_src_az_id = tgw_dst_az_id and
  start > 1763723920

19.Transit Gateway attachmentのus-east-1cのENIを削除が完了して20秒ほど経過した20-18-40以降で、送信元と送信先が同一AZの通信を確認します.png

パッと見たところus-east-1bであるuse1-az1のログがありませんね。

実際に以下で送信元がuse1-az1となるログをクエリしましたが、結果は0件でした。

SELECT 
  tgw_src_eni,
  tgw_dst_eni,
  tgw_src_az_id,
  tgw_dst_az_id,
  srcaddr,
  dstaddr,
  protocol,
  "start",
  "end",
  log_status,
  packets_lost_no_route,
  packets_lost_blackhole, 
  tcp_flags,
  flow_direction
FROM
  transit_gateway_flow_logs_partition_projection
WHERE
  datehour='2025/11/21/11' and
  dstaddr='10.0.10.11' and
  srcport=80 and
  tgw_src_az_id = 'use1-az1' and
  start > 1763723920

一方で、以下クエリでEC2インスタンスからのリクエストの通信についてはus-east-1bにルーティングされているものがありました

SELECT 
  tgw_src_eni,
  tgw_dst_eni,
  tgw_src_az_id,
  tgw_dst_az_id,
  srcaddr,
  dstaddr,
  protocol,
  "start",
  "end",
  log_status,
  packets_lost_no_route,
  packets_lost_blackhole, 
  tcp_flags,
  flow_direction
FROM
  transit_gateway_flow_logs_partition_projection
WHERE
  datehour='2025/11/21/11' and
  srcaddr='10.0.10.11' and
  dstport=80 and
  tgw_dst_az_id = 'use1-az1' and
  start > 1763723920

20.EC2インスタンスからのリクエストの通信については正しくus-east-1bにルーティングしています.png

以上のことから、設定のとおり、戻りの通信の際にus-east-1aに寄せられていることが分かりました。

先述のとおり、Transit Gateway attachmentのENIがSPOFとなるため、可用性が気になります。また、それだけでなく、AZを跨ぐことになるためレイテンシーおよび料金も気になります。

us-east-1bのEC2インスタンスからcheckip.amazonaws.comへアクセスし、レスポンスを受け取るまでの一連の通信をVPC Flow Logsでも確認したところ、以下のように最後にリージョナルNAT GatewayからTransit Gateway ENIへ通信をする際にAZを跨ぐような動きをしていました。

// EC2インスタンス → リージョナルNAT Gateway
{
  "version": 10,
  "account_id": "<AWSアカウントID>",
  "interface_id": "-",
  "srcaddr": "10.0.6.4",
  "dstaddr": "35.174.118.36",
  "srcport": 39886,
  "dstport": 80,
  "protocol": 6,
  "packets": 6,
  "bytes": 405,
  "start": 1763773589,
  "end": 1763773616,
  "action": "ACCEPT",
  "log_status": "OK",
  "vpc_id": "vpc-0eda45958335d3a92",
  "subnet_id": "-",
  "instance_id": "-",
  "tcp_flags": 3,
  "type": "IPv4",
  "pkt_srcaddr": "10.0.6.4",
  "pkt_dstaddr": "35.174.118.36",
  "region": "us-east-1",
  "az_id": "use1-az1",
  "sublocation_type": "-",
  "sublocation_id": "-",
  "pkt_src_aws_service": "-",
  "pkt_dst_aws_service": "EC2",
  "flow_direction": "ingress",
  "traffic_path": null,
  "reject_reason": "-",
  "resource_id": "nat-1f41ed76e254eb191",
  "encryption_status": null
}

// Transit Gateway attachment us-east-1b ENI → リージョナルNAT Gateway
{
  "version": 10,
  "account_id": "<AWSアカウントID>",
  "interface_id": "eni-076407fb33bc03ddb",
  "srcaddr": "192.168.0.156",
  "dstaddr": "35.174.118.36",
  "srcport": 39886,
  "dstport": 80,
  "protocol": 6,
  "packets": 6,
  "bytes": 405,
  "start": 1763773605,
  "end": 1763773626,
  "action": "ACCEPT",
  "log_status": "OK",
  "vpc_id": "vpc-0eda45958335d3a92",
  "subnet_id": "subnet-0e0268fc8bf2efd62",
  "instance_id": "-",
  "tcp_flags": 3,
  "type": "IPv4",
  "pkt_srcaddr": "10.0.6.4",
  "pkt_dstaddr": "35.174.118.36",
  "region": "us-east-1",
  "az_id": "use1-az1",
  "sublocation_type": "-",
  "sublocation_id": "-",
  "pkt_src_aws_service": "-",
  "pkt_dst_aws_service": "EC2",
  "flow_direction": "egress",
  "traffic_path": 1,
  "reject_reason": "-",
  "resource_id": "-",
  "encryption_status": null
}

// リージョナルNAT Gateway → IGW
{
  "version": 10,
  "account_id": "<AWSアカウントID>",
  "interface_id": "-",
  "srcaddr": "34.199.17.16",
  "dstaddr": "35.174.118.36",
  "srcport": 53551,
  "dstport": 80,
  "protocol": 6,
  "packets": 6,
  "bytes": 405,
  "start": 1763773589,
  "end": 1763773616,
  "action": "ACCEPT",
  "log_status": "OK",
  "vpc_id": "vpc-0eda45958335d3a92",
  "subnet_id": "-",
  "instance_id": "-",
  "tcp_flags": 3,
  "type": "IPv4",
  "pkt_srcaddr": "34.199.17.16",
  "pkt_dstaddr": "35.174.118.36",
  "region": "us-east-1",
  "az_id": "use1-az1",
  "sublocation_type": "-",
  "sublocation_id": "-",
  "pkt_src_aws_service": "EC2",
  "pkt_dst_aws_service": "EC2",
  "flow_direction": "egress",
  "traffic_path": 8,
  "reject_reason": "-",
  "resource_id": "nat-1f41ed76e254eb191",
  "encryption_status": null
}

// IGW → リージョナルNAT Gateway
{
  "version": 10,
  "account_id": "<AWSアカウントID>",
  "interface_id": "-",
  "srcaddr": "35.174.118.36",
  "dstaddr": "34.199.17.16",
  "srcport": 80,
  "dstport": 53551,
  "protocol": 6,
  "packets": 4,
  "bytes": 471,
  "start": 1763773596,
  "end": 1763773625,
  "action": "ACCEPT",
  "log_status": "OK",
  "vpc_id": "vpc-0eda45958335d3a92",
  "subnet_id": "-",
  "instance_id": "-",
  "tcp_flags": 19,
  "type": "IPv4",
  "pkt_srcaddr": "35.174.118.36",
  "pkt_dstaddr": "34.199.17.16",
  "region": "us-east-1",
  "az_id": "use1-az1",
  "sublocation_type": "-",
  "sublocation_id": "-",
  "pkt_src_aws_service": "EC2",
  "pkt_dst_aws_service": "EC2",
  "flow_direction": "ingress",
  "traffic_path": null,
  "reject_reason": "-",
  "resource_id": "nat-1f41ed76e254eb191",
  "encryption_status": null
}

// リージョナルNAT Gateway → EC2インスタンス
{
  "version": 10,
  "account_id": "<AWSアカウントID>",
  "interface_id": "-",
  "srcaddr": "35.174.118.36",
  "dstaddr": "10.0.6.4",
  "srcport": 80,
  "dstport": 39886,
  "protocol": 6,
  "packets": 4,
  "bytes": 471,
  "start": 1763773565,
  "end": 1763773595,
  "action": "ACCEPT",
  "log_status": "OK",
  "vpc_id": "vpc-0eda45958335d3a92",
  "subnet_id": "-",
  "instance_id": "-",
  "tcp_flags": 19,
  "type": "IPv4",
  "pkt_srcaddr": "35.174.118.36",
  "pkt_dstaddr": "10.0.6.4",
  "region": "us-east-1",
  "az_id": "use1-az1",
  "sublocation_type": "-",
  "sublocation_id": "-",
  "pkt_src_aws_service": "EC2",
  "pkt_dst_aws_service": "-",
  "flow_direction": "egress",
  "traffic_path": 1,
  "reject_reason": "-",
  "resource_id": "nat-1f41ed76e254eb191",
  "encryption_status": null
}

// リージョナルNAT Gateway → Transit Gateway attachment us-east-1a ENI
{
  "version": 10,
  "account_id": "<AWSアカウントID>",
  "interface_id": "eni-0e710793aaffb0a70",
  "srcaddr": "35.174.118.36",
  "dstaddr": "192.168.0.140",
  "srcport": 80,
  "dstport": 39886,
  "protocol": 6,
  "packets": 4,
  "bytes": 471,
  "start": 1763773588,
  "end": 1763773612,
  "action": "ACCEPT",
  "log_status": "OK",
  "vpc_id": "vpc-0eda45958335d3a92",
  "subnet_id": "subnet-06a99e501901ace49",
  "instance_id": "-",
  "tcp_flags": 19,
  "type": "IPv4",
  "pkt_srcaddr": "35.174.118.36",
  "pkt_dstaddr": "10.0.6.4",
  "region": "us-east-1",
  "az_id": "use1-az6",
  "sublocation_type": "-",
  "sublocation_id": "-",
  "pkt_src_aws_service": "EC2",
  "pkt_dst_aws_service": "-",
  "flow_direction": "ingress",
  "traffic_path": null,
  "reject_reason": "-",
  "resource_id": "-",
  "encryption_status": null
}

なお、Transit Gateway attachmentのENIがダウンした場合を表現しようと、Egress VPCのus-east-1aのサブネットのNetwork ACLのアウトバウンドルールで10.0.0.0/16への通信の拒否を設定しましたが、不発に終わりました。

これは以下記事で紹介されているとおり、アウトバウンドルールは、インスタンスから Transit Gateway へのトラフィックの評価には使用されないためです。

https://dev.classmethod.jp/articles/investigate-nacl-in-aws-transit-gateway-202312/

大雑把な設定だと可用性もレイテンシーも料金もZonal NAT Gatewayよりも悪化する可能性があるため個人的にはオススメしない

リージョナルNAT Gatewayを複数VPCのインターネットアウトバウンド集約できるか紹介しました。

結論できますが、以下理由から現状オススメしません。

  • ターゲットをTransit Gateway attachmentの一つのAZのIDのみ設定するような大雑把な設定だと、可用性もレイテンシーも料金もZonal NAT Gatewayよりも悪化する可能性があるため
  • AZ毎にCIDRブロックを把握した上できめ細かくルートテーブルを管理するのは運用負荷が高いため

リージョナルNAT GatewayのエッジルートテーブルのルートのターゲットとしてTransit Gatewayを指定できるようになるのを待ちましょう。

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

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

この記事をシェアする

FacebookHatena blogX

関連記事