🎃

Transit Gatewayを使ってNAT GatewayとVPC Endpointを1つのVPCに集約する

2021/12/23に公開

この記事は株式会社FOLIOアドベントカレンダーの21日目の記事です。

まとめ

まずこの記事のまとめです。

  • 前提条件
    • AWSアカウント複数運用している
    • VPCも複数存在している
    • VPC間通信にVPC Peeringではなく、Transit Gatewayを活用している
  • その前提条件であれば、一つのVPCにNAT GatewayとVPC Endpointが集約できるよという話
  • 集約するともともとTransit Gatewayを活用している場合は費用削減になる
  • VPCを追加するときにNAT GatewayとVPC Endpointを追加する必要がないので楽

課題

この記事を執筆するにあたって前々から以下のような課題感を持っていました。

  • AWSアカウントが複数あり、マルチアカウントで運用している
  • それに伴い複数のVPCがある
  • 各VPCにNAT GatewayやVPC Endpointがいて、これらの合計料金を見るとちょっと高い
  • 「このVPCにはこういうアプリケーションがあるから、このVPC Endpoint用意するぞ」という感じで各VPCごとに必要なものを把握して管理をするのが手間

Transit Gatewayを使うと1つのVPCにNAT GatewayとVPC Endpointを集約することができ、上記の問題を解決できるということで検証してみました。検証では以下のような構成を構築してみました。

検証

以下検証するにあたって行った作業です。

  1. Transit Gatewayをセットアップ
  2. Aggregation VPCにNAT Gateway, VPC Endpointの用意
  3. ルーテーブルの編集
  4. インターネット, VPC Endpointへの疎通確認

Transit Gatewayのセットアップ

まずVPC間通信のためにTransit Gatewayを用意します。そして、2つのVPC VPC A(10.0.0.0/16) Aggregation VPC(10.1.0.0/16)(=集約VPC) を作って、Transit Gatewayで相互通信できるようにします。(VPCの作成については割愛します)

そのためAWSのコンソールからTransit Gatewayを作成します。

オプションはデフォルトのままで大丈夫ですが特筆すべき点として以下のようなものがあります。

  • DNS サポート を有効
    • 別のVPCにあるVPC EndpointのPrivate IPを名前解決するのに必要
  • デフォルトルートテーブルの関連付け デフォルトルートテーブル伝播 を有効
    • 今回は検証のためデフォルトテーブルを使います
    • 後述のTransit GatewayにVPCをアタッチメントする際にデフォルトテーブルへのアソシエーション(関連付け)とプロパゲーション(伝播)が自動で行われるようになります。

次はTransit GatewayにVPCをアタッチメントします。コンソールの Transit Gateway アタッチメント の画面から作成してください。今回は VPC A Aggregation VPC 2つのVPCがあるため、それぞれTransit Gatewayアタッチメントを作成します。

作成したら状態がAvailableになるまで待ちましょう。Availableになったら コンソールの Transit Gateway ルートテーブル を確認します。するとTransit Gatewayのデフォルトテーブルが作成されており、先程作成したTransit Gatewayアタッチメントが自動的にアソシエーション/プロパゲーションされています。

この挙動はTransit Gatewayの作成時に デフォルトルートテーブルの関連付け デフォルトルートテーブル伝播 のオプションを有効したからです。

次にデフォルトテーブルの ルート タブを確認します。すると各VPCのCIDRへのルーティングが自動で設定されています。

これでTransit Gatewayのセットアップは完了です。

Aggregation VPCにNAT Gateway, VPC Endpointの用意

Transit Gatewayで2つのVPCを相互通信できるようにしたため、Aggregation VPCにNAT Gateway, VPC Endpointの用意します。

作成方法等の細かい部分は割愛しますが、VPC Endpointを作る際には以下のことに気をつけてください。

  • VPC A から疎通できるようにセキュリティグループを設定する
  • 疎通確認できればよいのでインターフェース型であれば選択するサービスは何でもよい
    • ゲートウェイ型のVPC Endpointは集約できない
    • 今回の検証では ec2 を選択

ルーテーブルの編集

必要なリソースをすべて作成し終わったので、ルーティングを編集して実際に疎通できるように設定します。

編集すべきルートテーブルは2種類あります。

  • Transit Gatewayのデフォルトテーブル
  • 各VPC, 各Subnetのルートテーブル

まずはTransit Gatewayのデフォルトテーブルです。インターネット(0.0.0.0/0)への通信をAggregation VPCに向けます。その際は静的ルートで追加しましょう。

次に各VPC, 各Subnetのルートテーブルです。

  • VPC A(10.0.0.0/16)
    • Public Subnet, Private Subnetのルートテーブルに Aggregation(10.1.0.0/16) への通信をTransit Gatewayにルーティング
    • Private Subnetのルートテーブルに インターネット(0.0.0.0/0) への通信をTransit Gatewayにルーティング`
  • Aggregation VPC(10.1.0.0/16)
    • Public Subnet, Private Subnetのルートテーブルに VPC A(10.0.0.0/16) への通信をTransit Gatewayにルーティング
    • Public Subnetのルートテーブルにも設定するのを忘れがちですが、忘れると VPC A のPrivate Subnetがインターネットに疎通できなくなるので注意

以上でルートテーブルの編集も終了です。これで実際に疎通できるようになっているはずです。

インターネット, VPC Endpointへの疎通確認

VPC A にEC2インスタンスをたてて、セッションマネージャでログインをして疎通確認を行います。インスタンスをたてる際のポイントとしては以下です。

  • Amazon Linux2のAMIを選択
  • IAM Roleをアタッチ
    • セッションマネージャが実行できるように AmazonEC2RoleforSSM 等のポリシーをアタッチ
    • EC2のAPIにリクエストできるよう AmazonEC2ReadOnlyAccess 等のポリシーをアタッチ

インスタンスがrunningになったらセッションマネージャでログインをしましょう。まずはインターネットに疎通できるか確認します。

$ curl -I https://folio-sec.com
> HTTP/2 200
> content-type: text/html; charset=utf-8
.
.
.

問題なく疎通できていそうです。

次に Aggregation VPC のVPC Endpointに疎通できるか確認します。先にnslookup等でVPC EndpintのDNS名から名前解決が行えるか確認します。

# Aggregation側にあるVPC EndpointのDNS名から名前解決をする
$ nslookup vpce-xxxxxxxx.ec2.ap-northeast-1.vpce.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   vpce-xxxxxxxx.ec2.ap-northeast-1.vpce.amazonaws.com
Address: 10.1.0.86 # Aggreation VPC内のPrivate IPが返却される

無事Private IPが返却されました。そしてこのIPと実際に疎通ができるか describe-instances 確認します

# 色々聞かれるが`Default region name [None]: ap-northeast-1` 入力するだけでOK
$ aws configure

# EC2 APIの問い合わせ先をAggregation VPCのVPC Endpiontに変更する
$ aws ec2 describe-instances \
  --endpoint-url https://vpce-xxxxxxxx.ec2.ap-northeast-1.vpce.amazonaws.com
{
    "Reservations": [
        {
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
.
.
.

無事疎通できていることが確認できました!

所感

無事1つのVPCにNAT GatewayとVPC Endpointが集約できました。すでにTransit Gatewayを使ってVPC間通信を行っている場合であれば、料金の節約にもなりそうです。

VPC Peeringを活用してVPC間通信を行っている場合ではNAT GatewayとVPC Endpointが減らせても、新たにTransit Gatewayの料金がかかるので、節約の効果はあまり期待できなさそうなので、そこはご注意です。

またVPCが後から追加された場合でも集約されたVPCにルーティングするだけでいちいちNAT GatewayとVPC Endpointを作成しなくて良くなります。

だた注意点としては今まで各VPCに存在してたNAT GatewayとVPC Endpointへの通信が一箇所に集中するようになるので、移行後はメトリクスの監視を行いましょう。

NAT Gatewayの性能であれば以下のように言及されています。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-basics

NAT ゲートウェイは 5 Gbps の帯域幅をサポートし、45 Gbps まで自動的に拡張します。これ以上の帯域幅が必要な場合は、リソースを分割して複数のサブネットに配置し、サブネットごとに NAT ゲートウェイを作成できます。

CloudWatchのメトリクスでもNAT Gatewayの PacketsDropCount あたりは監視したほうがよさそうですね。

Discussion