はじめに
こんにちは。DR & MLOps Group というところで働いている阿部といいます。Data Reliability & Machine Learning Operations の略で、データ基盤やML基盤を作って運用するグループです。 私はもともとは記事配信ロジックやデータ分析をやっているグループにいましたが、今年移ってきました。
こちらが紹介記事です: DREの使命とは?「数が神より正しい」と言うための正確性を求められる技術力 – Gunosiru
弊社のシステムは基本的にはAWSで動いていますが、とあるプロジェクトでGCPを使うことになりました。 その際にAWSとGCP間をプライベートなネットワークで繋ぐ必要があり、VPNを構築しました。AWSは複数のアカウントで運用されているので、それぞれ個別に設定してしまうと管理がたいへんです。そこで、割と最近 (2018年冬)出た Transit Gateway (TGW) を導入し、一元的に管理できるように構成しました。 VPN構築手順はなかなか煩雑でたいへんだったので、ここに記録を残しておきたいと思います。
まず弊社における AWS と GCP のネットワーク構成をざっくりと紹介し、その後VPN接続の方法を書いていきます。
AWSのネットワーク構成
弊社ではグノシー、ニュースパスといったプロダクト毎にアカウントが作られています。各アカウントと社内ネットワークで繋いだりプロダクト間同士で繋いだりすることがありますが、アカウント毎に設定すると管理が大変です。そこでハブとなるアカウントがあります。ここでは各プロダクトのアカウントをプロダクトアカウント、ハブのアカウントをホストアカウントと呼ぶことにしましょう。
元々ホストアカウントとプロダクトアカウント間のネットワークは個別に設定されていましたが、2019年10月のオフィス移転のタイミングでDirect Connectの対応が東京リージョンにも来たというのもあってTGWが全面的に導入されました。こちらの話はSREの茂木さんがブログを書いてくれると聞いています。楽しみですね。
オフィス内ネットワークから各アカウント内のVPCにアクセスするときはホストアカウントのTGWを経由します。具体的にはTransit Gateway を Resource Access Manager (RAM) を使ってプロダクトのアカウントと共有します。TGW には VPC と VPN がアタッチできて、TGW Route Tables というサービスを使ってルーティングをします。このあたりは後ほどもう少し説明します。
GCPのネットワーク構成
AWSと違ってGCPではアカウントは各個人に紐付いています
プロジェクトという単位でシステムの機能を構成していきます。弊社ではサービス運用はAWS、サービスに提供する単機能(=マイクロサービス)をGCPで運用するつもりだったので、プロジェクトは少し細かな粒度で作ることにしました。
ネットワークのハブとなるプロジェクトと、機能別のプロジェクトを作りました。それぞれVPCホストプロジェクト、サービスプロジェクトと呼びましょう。
GCPにはVPC Sharingというサービスがあって、VPCをプロジェクト間で共有することができます。VPCホストプロジェクトのVPCをサービスプロジェクトと共有します。
AWS と GCP 間での通信
VPN設定手順
さて、ここからが本題です。
GCPのVPNではClassic VPN と High-Availability (HA) VPN が選べます。Classic VPN はトンネルの本数は2本までですがHA VPNでは4本使うことができ、可用性が確保できます。今回はHA VPNを選びました。この場合、VPN Gateway にインターフェースが2つ付いていて、それぞれに2つずつトンネルを掘ります。
AWS側ではそれぞれのインターフェースに対して VPN Connection と Customer gateway を作ります。それをTGWにアタッチします。 図にするとこんな構成です。
手順を書いていきます。個人的にAWSとGCPのコンソールを英語に設定しているので、適宜読み取っていただければと思います。
いくつかの記事を参考にさせていただいたので、よければそちらも参照ください。 https://qiita.com/nagase/items/df18e308e6fc98e11aaa https://cloud.google.com/community/tutorials/using-ha-vpn-with-aws
GCP
まずはGCPでネットワークリソースを作っていきます。
最初に HA VPNを作ります。これは Hybrid Connectivity のメニューで VPN Setup Wizard から作ることができます。
最初のステップでVPN gatewayの名前、VPC、Regionを決めます。
Create & Continue ボタンを押すとインターフェースのIPアドレス(パブリック)が自動的に2つ割り振られます。GCP側は一旦ここで置いておきましょう。
AWS
次にホストアカウントのAWSコンソールで VPC -> Site-to-site VPC Connections のメニューから、VPN Connection を作ります(下図)。
インターフェースが2つなので、この作業は2回やります。
Target gateway type は Transit Gateway とし、対象の TGWを選択します。
Customer Gateway は新しく作成します。IPアドレスはGCPでVPNを作るときに自動的にできたインターフェースのIPアドレスです。 今回はBGP ASNは65000、Certificate ARNは空のままにしておきました。
Inside IP CIDR と Pre-Shared Key の欄は空のままにしておくと自動生成されます。
Advanced Options for Tunnel はそれぞれ編集することにしました。 IkeVersion (鍵交換プロトコルのバージョン) はデフォルトでは ikev1、ikev2ともにチェックが入っていますが、今回は ikev2 のみチェックするようにしました。ちなみにAWSではikev2は2019年2月に対応したらしいです。
一つ作ったら同様にもう一つ作ります。しばらくするとVPNが出来上がります。
完成したら Download Configuration ボタンを押します。Vendor を Generic にしてダウンロードします。2つ分ダウンロードしておきます。それぞれのファイルにトンネル2つ分の設定項目が書いてあります。不思議なことに、ダウンロードしたファイルの IKE version の項目が IKEv1 となっていましたが、コンソールではちゃんと ikev2 となっているので気にしなくて大丈夫っぽかったです。
GCP
GCPに戻ります。Peer VPN gateway は On-prem or Non Google Cloud にしておきます。
Peer VPN gateway nameのところで Create new peer VPN gateway を選択します。
名前は適当につけて、インターフェースは4つにします。
IPアドレスはAWSコンソールのSite-to-site VPN Connections からコネクションを選択すると出てくるトンネルのOutside IP Address を入力していきます。Connection 1 の Tunnel 1、Tunnel 2、Connection 2 の Tunnel 1、Tunnel 2 という順番につけていきましょう。 VPNトンネルは4つ使います。画面にRequired to connect to AWSとも書いてあります。
次にRouting Options で Cloud Routerを作ります。Google ASNは65000にしました。Advertise Routes の項目は今回はカスタムに設定しましたが、何か事情がなければ Advertise All subnets... としても大丈夫だと思います。
それぞれのVPNトンネル名前をつけ、対応する pre-shared keyを入力していきます。pre-shared keyはAWS側で生成してあります。ダウンロードした設定ファイルに書いてあるので、それを使いましょう。
次はBGPの設定になります。Peer ASNはAWSのデフォルト値64512にします。
トンネルごとに名前は適当に決めて、Cloud Router BGP IP と BGP peer IP を設定します。
それぞれダウンロードしたファイルにある Inside IP Address 欄の Customer Gateway と Virtual Private Gateway に対応します。ここらへんの設定は間違いやすいので注意です。
VPN設定はここまでで一通り完了です。ステータスが緑色になるのを祈りましょう。AWS側でもうまくいっていれば各種stateが緑色になっているはずです。
TGWを用いたルーティングの設定 (AWS)
まずは Resource Access Manager (RAM) を使ってTGWをプロダクトアカウントと共有します。ホストアカウントのRAMの管理画面に行って、Shared by me というところから Resource Sharesを作成します(下図)。
次に共有される側のアカウントにログインし、RAMの画面に行きます。Shared with meというところのResource sharesに共有されたTGWが現れるはずなので、共有されることをAcceptします。
この状態でVPCの画面のTransit Gatewaysを見ると共有されたTGWがあるはずです。Transit Gateways Attachment でプロダクトアカウントのVPCをTGWにアタッチします。
TGWホストアカウントに戻り、VPCの画面に行きます。Transit Gateway Route TablesメニューでTGWとVPC間のルートを作ることができます。CIDRとVPCのペアを設定します。
VPNもアタッチされているはずなので、同様にCIDRとVPNのペアも設定します。
Shared VPC の設定 (GCP)
サービスプロジェクトからVPNを使うためにShared VPCという機能を使います。
ホストプロジェクトのVPC Network メニューの Shared VPC を押します。Set up Shared VPCをクリックし、host projectを有効化します。共有したいVPCを選択し次に行きます。
そこでVPCネットワークの権限や共有するサブネットを指定します。
こうしておくと、サービスプロジェクトから共有されたVPC・サブネットワーク上にCompute Engineなどのリソースを作ることができるようになります。
Terraform
長々と書きましたが、実はGCP側ではTerraformで管理しているので設定ファイルを貼っておきます。AWSのホストアカウントはちょっとアレでまだTerraform化できていません。
まとめ
AWSとGCPのネットワーク構成を紹介し、AWSとGCP間のVPN構築手順をお伝えしました。
GCPの App Engine や AI Platform PredictionなどのマネージドなサービスはVPCの外にあり、VPC内と接続するには Serverless VPC Accessというサービスを使うらしいです。ただし、検証した当時は東京リージョンは対応しておらずあきらめていました。(このブログを書いているときに再度確認したら東京に来ていました!)
GCPネットワークを構築するのは社内では初めてだったので模索しながらでしたが、もっといい方法があるよ!などありましたらコメントいただけると嬉しいです。