AWS Transit Gateway はじめました

はてなでは一部のサービスはオンプレ環境と AWS を使用したクラウド環境の両方で構築しており、オンプレ環境と AWS VPC はインターネット VPN で接続しています。AWS のインターネット VPN は AWS VPN と AWS Classic VPN の2種類あります。AWS Classic VPN は AWS VPN の前身で、文字通り古いサービスで2019年9月にサービスの終了が予定されています。

はてなでは AWS Classic VPN から AWS Transit Gateway + AWS VPN という構成変更を選択し、事前検証を実施し、無停止での切り替えに成功したので、その内容を共有します。

AWS Transit Gateway とは?

AWS Transit Gateway (TGW) とは2018年11月に開催された AWS re:Invent 2018 で発表された AWS リソースを接続するためのサービスです。

http://reinvent.awseventsjapan.com/reinvent.awseventsjapan.com

www.slideshare.net

TGW を使うと何が嬉しいかというのは AWS の TGW のページに書かれています。

aws.amazon.com

上記ページの「AWS Transit Gateway を使用しない場合」と「AWS Transit Gateway を使用した場合」が TGW のメリットを端的に表していると思います。はてなでも複数の AWS アカウントとオンプレ設備を接続しているため、TGW が発表された当初から注目していました。

構成検討

オンプレ環境と AWS VPC との接続は以下の2つの目的で使用しています。

  • オンプレ環境と AWS VPC の通信
  • 異なる AWS アカウントの VPC 間で通信するときに経由するネットワーク

AWS Classic VPN は終了しますが、上記の要求を満たすための通信経路は必要なので AWS Classic VPN に依存しない以下のような構成に変更することを検討しました。

  • 案1: VPC Peering で VPC 間を接続する
  • 案2: AWS Classic VPN から AWS VPN に変更する
  • 案3: AWS Transit Gateway (TGW) を導入してオンプレ環境と AWS VPC を接続する

また、今回の構成変更とは別の話題として、将来的には AWS アカウントを分離することを検討していました。そのため、オンプレ設備やAWS アカウント間の接続は極力シンプルな構成にしておきたいという事情があります。

このような事情を考慮すると

  • 案1 は AWS アカウントの増加に伴い VPC Peering が増えると管理する手間が爆発的に増えそう。
  • 案2 は AWS Classic VPN から AWS VPN に変更する時に VPN を収容している Virtual Private Gateway (VGW) を作り直して、VPC への VGW のアタッチとデタッチを実施する必要があり、どうしてもネットワーク断が発生してしまう。また、ネットワーク断について自分たちで制御することができない。
  • 案3 は将来的に AWS アカウント間の接続に TGW の採用を検討していたので、この機会に検証をして導入してしまうのが良さそう。

ということで、案3 をベースにして構成変更を実施することにしました。

ただし、TGW と VPC Peering ではネットワークコスト的には VPC Peering が有利なので、通信量に応じて VPC Peering に切り替えるという選択肢は十分あり得ます。

構成変更手順

TGW 構成変更前
TGW 構成変更前
TGW 構成変更後
TGW 構成変更後

切り替え前の AWS Classic VPN 経由の経路と切り替え後の TGW + AWS VPN を経由する構成図は上記のとおりです。切り替え前は VPC を構築している AWS アカウントに作成した AWS Classic VPN を経由していますが、切り替え後は VPC を構築している AWS アカウトとは別の TGW 専用の AWS アカウントに AWS VPN を構築しています。また、切り替え前後では VPN 終端装置は別の機器を使用しています。

構成変更は大きく分けて、事前作業と当日作業の2つを実施しています。事前作業とは既存の構成や通信に全く影響が無くいつ実施しても良い作業、当日作業は微小ではあるが通信影響が発生する可能性があるので、あらかじめサービス開発チームにメンテナンスを実施することを共有し実施する作業という区分です。

事前作業

使用する TGW を作成する

TGW は専用の AWS アカウントを作成し、その中に TGW を作成しました。作成時には TGW に接続する VPC を構築している AWS アカウントに AWS Resource Access Manager (RAM) で TGW を共有しておきます。

また、TGW 作成時の注意ポイントとして、以下の2つの機能を無効にしています。

  • Default route table association
  • Default route table propagation
  • Auto accept shared attachments

"Default route table association" と "Default route table propagation" は VPC などをアソシエートした時に TGW で使用する Route Table に経路が登録され通信が始まってしまい、作業時に通信の制御が難しくなってしまうため無効にしています。

また、"Auto accept shared attachments" は今回のように異なる AWS アカウントでの制御は RAM を使うので無効にしています。

TGW に接続する VPN と VPC をアタッチする

事前作業ではあくまでもアタッチメントを作成するまでにとどめて、プロパゲートとアソシエートは当日作業に実施します。感覚としてはルーターにネットワークケーブルは接続しているけど、ポートを閉じておいて、準備が整ってからルーターのポートを開けるような感じです。

また、AWS VPN は新規で作りますが、いつものとおり AWS VPN を作ろうとすると VPN を接続する VGW を選択する必要があり、今回は VGW に接続する必要はないので、TGW のアタッチメントを作成する時に AWS VPN を作りました。

AWS VPC に TGW を参照する Route Table を作成する

TGW と VPC の通信は双方の Route Table を参照して、通信先に応じた通信経路が決定されます。つまり、

  • TGW から VPC への通信は TGW の Route Table に記載し
  • VPC から TGW への通信は VPC の Route Table に記載する

という必要があります。

今回の作業では VPC の Route Table には AWS Classic VPN を経由する経路が登録されています。したがって、TGW 経由の通信に切り替えるためには VPC の Route Table に登録されている経路を変更する必要があります。

変更前の VPC の Route Table には AWS Classic VPN を通じてオンプレ環境などの経路が BGP で広報されており、VGW は AWS Classic VPN で広報されている経路を Route Table に伝播させています。AWS の Route Table は通信先のプレフィック長が同じであれば伝播されている経路よりも手で入れた経路が勝つので、TGW 向けの経路を手で入れれば良いはずです。

ただし、オンプレ環境から広報されている経路は数十経路あり、また、subnet ごとに Route Table を定義しているため、切り替え時には100以上の経路を手で入れる必要があります。awscli などでスクリプト化したり、AWS CDK や CloudFormation などで変更することも考えましたが、当日の作業で手数が多くなってしまい、ちょっと躊躇してしまいます。

今回はあらかじめ TGW を参照する Route Table を準備しておき、当日作業中に参照する Route Table を入れ替える方針にしました。このように Route Table を別に作っておくことで以下のメリットがあります。

  • 当日作業で問題が出た場合の切り戻しも楽になりそう
  • そもそもプレフィックス長を揃える必要がないので、Route Table の経路数を少なくできる

また、事前検証でサブネットに関連付けた Route Table を入れ替えるだけであれば、既存の通信に影響が無いことが確認できたので、Route Table の入れ替えを採用しました。

当日作業

事前作業によって VPC から TGW を経由したオンプレ設備への通信経路は物理的に結線されているが、論理的には疎通がない状態になっています。当日作業では通信経路上の結線ポイントで通信を開始していくようなイメージです。

当日作業開始時の状態
当日作業開始時の状態

AWS VPN を TGW の Route Table にプロパゲートする

AWS VPN を TGW の Route Table にプロパゲートした状態
AWS VPN を TGW の Route Table にプロパゲートした状態

オンプレ環境と TGW への通信経路を確立させます。具体的には事前作業で作成した AWS VPN とのアタッチメントを TGW の Route Table にアソシエートして、プロパゲートする、という感じです。

この作業を実施する直前までは TGW の Route Table には経路が書かれていません。AWS VPN とのプロパゲートが完了したら TGW の Route Table に AWS VPN を経由してオンプレ環境の経路が BGP で流れ込みます。この作業が完了したときには TGW の Route Table にはオンプレ環境への経路が書かれているのみです。したがって、TGW から AWS VPN へ広報するべき経路は存在しないため、オンプレ環境のネットワーク経路には変化がありません。

VPC を TGW の Route Table にプロパゲートする

VPC と TGW の通信経路を確立させます。AWS VPN とのプロパゲートと同じ手順を踏みます。

VPC を TGW の Route Table にプロパゲートした状態
VPC を TGW の Route Table にプロパゲートした状態

VPC とのプロパゲートが完了すると、TGW の Route Table には VPC にアサインしている CIDR ブロックを対象とした経路が登録されます。このため、この作業が完了した時点で TGW から VPC 向けの経路の広報がオンプレ環境に開始されれます。

オンプレ環境内では AWS Classic VPN への経路も生きているため、VPC への通信経路は AWS Classic VPN と AWS VPN + TGW の2種類の経路が存在することになります。実際にはやりませんでしたが、この時点でオンプレ環境内の経路を調整して、AWS VPN を優先するような経路制御をしておくと良いかもしれません。

また、この時点では VPC 内には TGW を経由する経路は登録されていないので、新しく追加されるのはオンプレ環境から VPC への経路のみです。

ここで問題が発生した場合はプロパゲートの削除の他、オンプレ環境の VPN 終端装置で VPN を強制的に落とすなどを検討していました。

VPC の Route Table に TGW 向けの経路を設定する

VPC から出ていく経路をAWS Classic VPN から TGW 経由に変更します。事前作業で作成しておいた Route Table に置き換えるだけです。

この作業によって VPC とオンプレ環境の双方向で TGW を経由する経路ができあがります。

AWS Classic VPN の VPN トンネルを落とす

これまでの作業でとくに問題がおきてないことを確認したら、最後に残った AWS Classic VPN を落とします。

ここまでの作業が完了したら、オンプレ環境と AWS VPC の通信は全て TGW 経由に切り替わっています。

AWS Transit Gateway で知っていると良いこと

今回の TGW を採用するにあたって、はてな内で TGW の検証を実施しました。実施時に気づいたことを書いておきます。

AWS Transit Gateway をクロスアカウントで使う時に気をつけるポイント

今回は単一の AWS アカウントで構築している VPC とオンプレ環境を接続するために TGW を採用しましたが、将来的には TGW をハブとして複数の AWS アカウントで構築している VPC をスター型で接続することを想定しています。このようにクロスアカウントで TGW を使用する場合は AWS Resource Access Manager (RAM) で TGW を複数のアカウントで共有可能にしておくと必要があります。

AWS RAM で TGW を共有するとすると、TGW を作成する AWS アカウントはどのように選択するべきかという問題があります。今回は TGW 専用の AWS アカウントを作成することにしました。この AWS アカウントは TGW (とオンプレ環境と接続している VPN)のみを作成するとして、TGW を使用する AWS アカウントに対して TGW を共有するという方針にしました。

現時点では AWS RAM を使用して TGW を共有した場合、共有元の AWS アカウントで TGW に Name タグを設定しても共有した AWS アカウントにはタグ情報が反映されないという問題があります。また、共有先の AWS アカウントで TGW の Name タグを設定しようとしても、TGW の所有者ではないため設定できません。このため、共有先の AWS アカウントでは tgw-XXXXX というリソース ID のみで判別する必要があります。

また、TGW に限らず RAM で AWS リソースを共有する場合は、各種操作をするときに操作対象のアカウントがリソースの共有元か共有先かを強く意識する必要があります。メンテナンスの作業手順書では操作時のアカウントはわかりやすく書くなどの工夫がないと怖いな、という印象がありました。

AWS Transit Gateway における Attach / Propagate / Associate という考え方

TGW を使う時に気をつける用語として以下の3つがあります

  • アタッチ
  • アソシエート
  • プロパゲート

TGW におけるアタッチとはAWS VPC や AWS VPN などを TGW に接続することを意味しています。ただしアタッチしただけでは TGW を使うことはできません。TGW のアタッチメントが作られるだけです。今回の事前作業でもアタッチメントのみを作り、プロパゲートとアソシエートは当日作業としています。

TGW を使うためには TGW のアタッチメントを TGW 内の Route Table に関連づける必要があります。これがアソシエートと呼ばれる操作に相当します。TGW にアタッチしている AWS リソースからのパケットは TGW のアタッチメントを通じてアソシエートした Route Table にパケットが送信されるようになります。ただし、アソシエートしただけでは TGW の Route Table には経路が登録されません。

TGW の Route Table にアタッチしている AWS リソースへの経路を登録するためには Route Table へのプロパゲートという操作が必要です。このプロパゲートによって TGW の Route Table に経路が伝播するようになります。

注意するべき点は複数の Route Table に対してプロパゲートは可能ですが、アソシエートできる Route Table は1つのみという制約があります。つまり、TGW に接続する AWS リソースを TGW の Route Table とアソシエートする時は 1:1 の関係ですが、TGW に接続する AWS リソースを TGW の Route Table とプロパゲートする場合は 1:N の関係を選択できます。アソシエートとプロパゲートは異なる制約を持つので TGW を用いた構成を検討する時に注意が必要です。

また、プロパゲートによって TGW にアタッチしている VPC の Route Table に TGW の Route Table の内容は伝播しません。このため、VPC のサブネットで使用している Route Table には TGW を経由するべき通信についての経路を登録する必要があります。

VPC を TGW にアタッチすること

今までは漠然と VPC を TGW にアタッチすると書いてきましたが、アタッチの詳細については触れていません。ここでは VPC とのアタッチメントを作成することの詳細について書きます。

VPC の構成要素としては AZ やサブネットなどがあります。TGW で VPC にアタッチメントを作成するときにはどのサブネットにアタッチするかを選択する必要があります。注意点として単一の AZ 内で TGW にアタッチできるサブネットは1つだけという制約があります。例えば、よくある構成として AZ 内にパブリックサブネットとプライベートサブネットを構築している場合はパブリックサブネットかプライベートサブネットの片方としか TGW をアタッチできません。

VPC から TGW へ通信するためには VPC 内のサブネットで使用している Route Table に経路を入れる必要がある、と述べました。つまり Route Table に TGW に接続しているネットワークへの経路を TGW に転送するための経路が必要です。ここで TGW にアタッチしていないサブネットで使用している Route Table にどのような経路を書けば良いか、という疑問が生じます。正解は同じ AZ で作成している他のサブネットが TGW とアタッチしている場合は何も考えずに TGW 向けの経路を書くと TGW 経由の通信が可能になります。直感に反していますが、同一 AZ の他のサブネットが TGW にアタッチしていれば、ネットワーク的には問題なく通信ができるようになっているようです。

今回の構成変更の対象になっている VPC でも1つの AZ にパブリックサブネットとプライベートサブネットを構築していたので、プライベートサブネットに TGW をアタッチする構成にしました。

一緒にクラウド環境とオンプレ環境を作り変えてみませんか?

今回は AWS Classic VPN のサービス終了というキッカケではありましたが、クラウド環境とオンプレ環境の構成変更ネタはいっぱいあります。はてなでは一緒に攻めの構成変更をしていく仲間を募集しています!!興味のある方は話だけでも聞いてみませんか?