実践!AWS Transit Gateway を分離環境と共通環境に分けた構成パターン #reinvent
re:Invent が終わって、はや1週間。各所で re:Invent 報告会が行われている今日このごろですが、みなさん時差ボケはなおりましたか。私は夜型の生活からなかなか戻れておりませぬ。。
さて、東京リージョンのリリースが待ち遠しい AWS Transit Gateway も、使ってみた系の記事が多く見られ、その注目度の高さが伺えます。とりあえず試すには、デフォルトルートテーブル1つで、すべての VPC/VPN を Any-to-Any で接続してしまうのが手っ取り早く、検証記事も書きやすいのですが、実運用を考えると Any-to-Any というのは考えにくいです。Deep Dive セッションなどを観て、「ふむふむ。ルートテーブルで環境分離するんだね」ということは理解していたのですが、実際どうやるんかなー、というのが気になったので、試してみました。 というのが、今回の記事です。
構成図
今回作ってみた環境は、こんな感じです。
- オンプレ環境はないので、VyOS を使って疑似環境として VPN 接続しています。
- VPN および、共通環境からはすべての VPC/VPN への通信が可能です。
- 分離環境として VPC1、VPC2 を作成しました。例えば、VPC1 からは VPN と共通環境への通信は可能ですが、VPC2 への通信は出来ません。(VPC2 からの場合は VPC1 に通信できません)
ざっくり、やりたいことを理解いただいたかと思いますので、それでは試していきましょう!
やってみた
おおまかに以下のことをやります。作業の順番については、これが must ではないので、やりやすいように変えてください。
- Transit Gateway の作成
- Transit Gateway ルートテーブルの作成
- Transit Gateway アタッチメントの作成
- Transit Gateway の関連付けとルート伝播の設定
- VPC ルートテーブルの設定
- 疎通確認
Transit Gateway の作成
Create Transit Gateway
から Transit Gateway(以降、TGW) の作成を行います。とりあえず使ってみた系の記事では、Default route table association
と Default route table propagation
がデフォルトのチェック状態のまま作成されていると思いますが、今回は Any-to-Any ではない環境を作りたいので、この 2 箇所のチェックを外して作成します。
すると、このように Association route table ID
と Propagation route table ID
が空っぽの状態の TGW が出来上がります。
Transit Gateway ルートテーブルの作成
次に、TGW のルートテーブルを作成します。Transit Gateway Route Tables
のコンソールを開き、Create Transit Gateway Route Table
をクリックします。名前と、先程作成した TGW ID を指定するだけです。
ここでは 2 つのルートテーブルを作成しました。
- 共通環境用のルートテーブル(VPN、共通サービス VPC が使います)
- 分離環境用のルートテーブル(VPC1、VPC2 が使います)
Transit Gateway アタッチメントの作成
次に TGW のアタッチメントを作成します。Transit Gateway Attachments
のコンソールを開き、Create Transit Gateway Attachment
をクリックします。今回、オンプレ想定環境は VPC 上に作成していますが、VPN 接続で検証を行いたいため、VPN タイプを選択します。カスタマーゲートウェイも新規作成しますので New
を選び、VPN ルータのパブリック IP を指定します。あと、VPN は BGP を使用したいので Dynamic
を選択し、作成します。
カスタマーゲートウェイが作成されていますので、VPN 接続
のコンソールを開き、設定のダウンロード
から Config をダウンロードし、VPN ルータに適用します。
次に、VPC タイプの TGW アタッチメントを作成しますので、再度、Transit Gateway Attachments
のコンソールを開き、Create Transit Gateway Attachment
をクリックします。VPC タイプを選択します。今回、オンプレの疑似環境を除いて 3 つの VPC がありますので、3 つのアタッチメントをそれぞれ作成します。サブネットの指定ですが、1 AZ につき 1 サブネットしか指定できませんので、設計時にはご注意ください。
これで、1 つの VPN アタッチメント、3 つの VPC アタッチメントが作成できました。
Transit Gateway の関連付けとルート伝播の設定
それでは、関連付けとルート伝播設定を行っていきましょう。Transit Gateway Route Tables
のコンソールを開き、まずは共有サービス用のルートテーブルから設定していきます。対象の TGW ルートテーブルを選択し、Associations
タブから、Create association
をクリックします。
関連付ける TGW アタッチメントを選択し、関連付けを行います。
共通環境用の TGW ルートテーブルには、VPN アタッチメントと、共通サービス VPC アタッチメントを関連付けています。
同じ手順で、分離環境用の TGW ルートテーブルには、VPC1 アタッチメント、VPC2 アタッチメントを関連付けています。
次に、ルート伝播の設定を行います。まず共通環境用のルートテーブルを選択し、Propagations
タブを開き、Create propagation
をクリックします。関連付けのときと同様に、ルート伝播するアタッチメントを選択し、設定します。
共通環境用には、関連付けと同じ VPN アタッチメントと、共通サービス VPC アタッチメントに加えて、VPC1 アタッチメント、VPC2 アタッチメントを設定しています。
次にルートの設定ですが、今回の対象はすべてルート伝播により自動登録されています。手動登録する場合は、Routes
タブから、Create route
をクリックし、以下のように対象の CIDR と アタッチメントを指定し、作成します。(TGW ではブラックホールのルーティングが許容されており、強制的にドロップさせたい場合はブラックホールにチェックを入れます)
共通環境用のルートテーブルは以下のようになりました。
今回は VPN アタッチメントを Dynamic(BGP)
で作成していますので、このルートテーブルは VPN ルータ側にも伝播されています。
$ sho ip bgp BGP table version is 0, local router ID is 172.16.0.18 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> 172.16.0.0/27 0.0.0.0 1 32768 i * 192.168.0.0 169.254.47.45 100 0 64512 e *> 169.254.46.197 100 0 64512 e * 192.168.10.0 169.254.47.45 100 0 64512 e *> 169.254.46.197 100 0 64512 e * 192.168.20.0 169.254.47.45 100 0 64512 e *> 169.254.46.197 100 0 64512 e
分離環境用のルートテーブルも同様にルート伝播と、ルート設定を行います。こちらは、VPN と 共通サービス VPC のみが対象となりますので、ルート伝播設定は下記のとおりです。
ルートテーブルは以下のようになります。
VPC ルートテーブルの設定
VPC ルートテーブルは以下のようになっています。 VPC1、VPC2 のルートテーブルでは、共通サービス VPC の 192.168.0.0/24
のみに限定しても良いのですが、今回は TGW ルートテーブルを参照しても、VPC1、VPC2 間で疎通できないことを確認する意味でも、すべての VPC を包含する CIDR で指定しました。
VPC1 用
VPC2 用
共通サービス用
オンプレ想定用
192.168.0.0/16
を eni
に向けているのは、VyOS で VPN を設定している関係上、戻りのルートが必要だったためです。TGW とは関係ないので、読み流していただいて結構です。
Transit Gateway 利用時の VPC ルートテーブル設計(思いつき)
先程、VPC1, VPC2 間が TGW ルートテーブルを参照しても疎通できないことを確認するため、と書きましたが、設計の観点でもう 1 つ理由あります。それは、今後 VPC がスケールしていくことを考慮する場合、このように設定しているほうが、TGW ルートテーブル側でコントロールできるというメリットがあります。
たとえば、VPC 毎の CIDR でキッチリ指定している場合、仮に共通サービスが増えて VPC が新設されたとします。その場合、VPC 毎にあらたな CIDR のルートを追加設定してまわる必要があります。既存で 10、20 の VPC がある場合どうします、、。これって Transit Gateway がリリースされる前の手間とあまり変わらないのではないでうしょか??なので、可能であるなら TGW のルートテーブルでコントロールできる設計に寄せておいたほうが、後々の VPC 拡張時の対応負荷が減るんじゃないかと思います。
TGW を使うメリットの一部として、複雑な VPC 環境の運用管理コスト削減があると思いますので、そこを潰してしまわないように考慮した設計がポイントになりそうですね。
疎通確認
結論としては、想定どおり VPC1 → VPC2 もしくは VPC2 → VPC1 のみが疎通不可となり、共通環境についてはすべて疎通 OK でした。結果ログは最後に掲載しておきます。
さいごに
これまでデフォルトルートテーブルでしか TWG を触っていなかったのですが、今回、分離環境と共通環境とを区別して TGW ルートテーブルを作ってみたことで、より実用的な使い方がわかりました。本当は、共通サービスも動かしたうえで確認したいことがあったのですが、ひとまずは疎通確認まで! ということで今回は締めたいと思います。共通サービスについては、また別記事としてご紹介します!
以上!大阪オフィスの丸毛(@marumo1981)でした!
付録:疎通結果ログ
オンプレ(想定)環境から (すべて疎通 OK)
$ ping -c 3 192.168.0.12 PING 192.168.0.12 (192.168.0.12) 56(84) bytes of data. 64 bytes from 192.168.0.12: icmp_seq=1 ttl=252 time=3.70 ms 64 bytes from 192.168.0.12: icmp_seq=2 ttl=252 time=2.79 ms 64 bytes from 192.168.0.12: icmp_seq=3 ttl=252 time=2.63 ms --- 192.168.0.12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 2.638/3.045/3.705/0.470 ms $ ping -c 3 192.168.10.51 PING 192.168.10.51 (192.168.10.51) 56(84) bytes of data. 64 bytes from 192.168.10.51: icmp_seq=1 ttl=252 time=2.78 ms 64 bytes from 192.168.10.51: icmp_seq=2 ttl=252 time=2.35 ms 64 bytes from 192.168.10.51: icmp_seq=3 ttl=252 time=2.20 ms --- 192.168.10.51 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 2.201/2.447/2.783/0.249 ms $ ping -c 3 192.168.20.23 PING 192.168.20.23 (192.168.20.23) 56(84) bytes of data. 64 bytes from 192.168.20.23: icmp_seq=1 ttl=252 time=3.00 ms 64 bytes from 192.168.20.23: icmp_seq=2 ttl=252 time=5.68 ms 64 bytes from 192.168.20.23: icmp_seq=3 ttl=252 time=2.35 ms --- 192.168.20.23 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 2.359/3.681/5.684/1.441 ms
共有サービス環境から (すべて疎通 OK)
$ ping -c 3 172.16.0.17 PING 172.16.0.17 (172.16.0.17) 56(84) bytes of data. 64 bytes from 172.16.0.17: icmp_seq=1 ttl=253 time=3.88 ms 64 bytes from 172.16.0.17: icmp_seq=2 ttl=253 time=2.96 ms 64 bytes from 172.16.0.17: icmp_seq=3 ttl=253 time=3.47 ms --- 172.16.0.17 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 2.963/3.440/3.887/0.383 ms $ ping -c 3 192.168.10.51 PING 192.168.10.51 (192.168.10.51) 56(84) bytes of data. 64 bytes from 192.168.10.51: icmp_seq=1 ttl=254 time=2.06 ms 64 bytes from 192.168.10.51: icmp_seq=2 ttl=254 time=0.969 ms 64 bytes from 192.168.10.51: icmp_seq=3 ttl=254 time=0.920 ms --- 192.168.10.51 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 0.920/1.318/2.067/0.531 ms $ ping -c 3 192.168.20.23 PING 192.168.20.23 (192.168.20.23) 56(84) bytes of data. 64 bytes from 192.168.20.23: icmp_seq=1 ttl=254 time=0.892 ms 64 bytes from 192.168.20.23: icmp_seq=2 ttl=254 time=0.281 ms 64 bytes from 192.168.20.23: icmp_seq=3 ttl=254 time=0.268 ms --- 192.168.20.23 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2049ms rtt min/avg/max/mdev = 0.268/0.480/0.892/0.291 ms
VPC1から (VPC2 のみ疎通不可)
$ ping -c 3 172.16.0.17 PING 172.16.0.17 (172.16.0.17) 56(84) bytes of data. 64 bytes from 172.16.0.17: icmp_seq=1 ttl=253 time=3.35 ms 64 bytes from 172.16.0.17: icmp_seq=2 ttl=253 time=2.34 ms 64 bytes from 172.16.0.17: icmp_seq=3 ttl=253 time=2.56 ms --- 172.16.0.17 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 2.346/2.756/3.353/0.431 ms $ ping -c 3 192.168.0.12 PING 192.168.0.12 (192.168.0.12) 56(84) bytes of data. 64 bytes from 192.168.0.12: icmp_seq=1 ttl=254 time=2.02 ms 64 bytes from 192.168.0.12: icmp_seq=2 ttl=254 time=0.988 ms 64 bytes from 192.168.0.12: icmp_seq=3 ttl=254 time=1.02 ms --- 192.168.0.12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 0.988/1.343/2.020/0.480 ms $ ping -c 3 192.168.20.23 PING 192.168.20.23 (192.168.20.23) 56(84) bytes of data. --- 192.168.20.23 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2029ms
VPC2から (VPC1 のみ疎通不可)
$ ping -c 3 172.16.0.17 PING 172.16.0.17 (172.16.0.17) 56(84) bytes of data. 64 bytes from 172.16.0.17: icmp_seq=1 ttl=253 time=3.35 ms 64 bytes from 172.16.0.17: icmp_seq=2 ttl=253 time=2.43 ms 64 bytes from 172.16.0.17: icmp_seq=3 ttl=253 time=2.46 ms --- 172.16.0.17 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 2.430/2.749/3.353/0.431 ms $ ping -c 3 192.168.0.12 PING 192.168.0.12 (192.168.0.12) 56(84) bytes of data. 64 bytes from 192.168.0.12: icmp_seq=1 ttl=254 time=0.962 ms 64 bytes from 192.168.0.12: icmp_seq=2 ttl=254 time=0.214 ms 64 bytes from 192.168.0.12: icmp_seq=3 ttl=254 time=0.233 ms --- 192.168.0.12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2034ms rtt min/avg/max/mdev = 0.214/0.469/0.962/0.349 ms $ ping -c 3 192.168.10.51 PING 192.168.10.51 (192.168.10.51) 56(84) bytes of data. --- 192.168.10.51 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2034ms