Terraform で GCP Classic VPN: トンネルをルートベースにする
Classic VPN ではラベルが動作を決めるのではありません。ルートベースとは、ローカルセレクタ 0.0.0.0/0、一致するリモートセレクタ、明示的なルートのことです。
プランは問題なく適用され、トンネルは起動し、コンソールはポリシーベースと呼びますが、それでも通信は通りません。Terraform リソースでルートベースの切り替えを探しても、そんなフィールドは存在しないため何も見つかりません。Classic VPN ではルートベースの動作は選ぶモードではありません。ローカルトラフィックセレクタが0.0.0.0/0で、リモートセレクタが実際に使いたいネットワークを列挙し、ルートがトンネルを指すときに得られるものです。三つの条件がそろえば、ラベルもそれに従います。
誤解: トンネルモードのフィールド
コンソールのラベルは、API がセレクタで見ている内容を反映しているだけです。リソースにはルートベースと書かれていないので、真に設定するものはありません。
そのフィールドを探すのに問題の最初の一時間を使い、セレクタの値を読むのに最後の五分を使います。
ここでのルートベースの意味
Google は Classic VPN のルートベースのトンネルを、ローカルセレクタが0.0.0.0/0であるポリシーベースのトンネルとして文書化しています。名前が付くのはリモート側の範囲だけで、ローカル側は任意のアドレスとして扱われます。だから設定の中で目印になるのはモードではなく値です。両方のセレクタを明示的に書き、プランの出力で確認してください:
local_traffic_selector = ["0.0.0.0/0"]
remote_traffic_selector = ["10.20.0.0/16"]
その抜粋のピアプレフィックスは例示で、重要なのは形です。
ルートは別のオブジェクト
トンネルのオブジェクトはルートをインストールしません。パケットがトンネルのポリシーに一致しても行き先がないことがあります。次ホップを決めるのは VPC のルーティングテーブルだからです。ルートには宛先範囲、ネットワーク、次ホップとしてのトンネル、そしてより広い範囲に勝つ優先度が必要で、これを忘れると、接続済みと報告するトンネルと、VPC から一度も出ない疎通確認が残ります。
resource "google_compute_route" "office" {
name = "office-via-vpn"
dest_range = "10.20.0.0/16"
network = google_compute_network.vpc.name
next_hop_vpn_tunnel = google_compute_vpn_tunnel.to_office.id
priority = 1000
}
ルートはトンネルと同じモジュールで作成し、レビューで両者が離れないようにします。
ピア側でセレクタを鏡像にする
リモート側の機器は鏡像で設定する必要があり、そのローカル範囲がこちらのリモートセレクタであり、そのリモート範囲は使う予定の GCP サブネットを覆わなければなりません。どちらかの側が狭まると、フェーズ 1 が成功してもフェーズ 2 は失敗します。コンソールでは正しく見えるのに通信が流れない設定の、最もよくある形です。
変更レビューの際に、両側のセレクタを並べて印字してください。
静的アドレスを二回の適用に分ける
予約アドレスとそれを参照するトンネルを一度の適用で作るのは、転送ルールが使う前にアドレスが存在している必要があるため、不安定さのよく知られた原因です。まずアドレスのリソースだけを適用し、次にゲートウェイ、転送ルール、トンネルを加えて再度適用します。Terraform は二度目の実行で状態から既存のアドレスを読み、再利用します。これを飛ばすと、適用のたびにトンネルが新しいパブリックアドレスを受け取り、そのたびにピアの設定が壊れます。
今は二度の適用のほうが、リリースごとにピアを変えるより安くつきます。
ラベルではなくネゴシエーションを検証する
適用後に、トンネルが接続済みと報告していること、ルートが意図した次ホップで存在すること、ピアがフェーズ 1 とフェーズ 2 の両方が起動していると報告することの三つを個別に確認します。
トンネルが起動しているのにフェーズ 2 が落ちているなら、両側でセレクタの認識が食い違っています:
- 片側が、もう片側が挙げていないサブネットを挙げています。
- 片側が、もう片側が狭めた集約を使っています。
- ルートは存在しますが、別のトンネルを指しています。
Classic VPN は HA VPN より SLA の低い単一のトンネルであり、HA VPN は二つのインターフェース、二つのトンネル、そして異なるリソース種別の BGP を使います。クラシックな例を HA 構成にコピーして、セレクタのフィールドが同じように振る舞うと期待するのは、避ける価値のある別の誤りです。トンネルのフィールド自体はgoogle_compute_vpn_tunnel のリファレンスに文書化されています。