Private Service Connectを使用して、EC2からBigQueryにVPN経由でアクセスする方法 (Part2: VPN構築編)

AWS/Google Cloud間をVPNで接続し、EC2からBigQueryへVPN経由でアクセスする方法を試してみました。Private Service Connectを使用して、Google CloudのVPN内にエンドポイントを作成してGoogle Cloud APIへプライベート接続が可能です。また、Google Cloud APIのDNSをAWSでも使えるようにしてみました。この記事では、AWS/GCP間をVPN接続した内容を記載します。
2021.10.11

データアナリティクス事業本部の笠原です。

AWSとGCPをVPN接続して、EC2からBigQueryへアクセスする方法を試してみました。

以下、3つの記事に分けて掲載いたします。

  1. 環境準備編
  2. VPN構築編 (この記事)
  3. PSC/DNS設定編

この記事では、前回作成した検証環境にVPNを構築します。

構成内容

前回は以下のような構成の検証環境を構築しました。

本記事では以下のようなVPN接続を設定したいと思います。

なお、VPN設定については以下の記事に詳細が掲載されています。

今回は上記記事の「パターン3」の構成になります。

ちなみにGCPのVPN接続のうち、「Classic VPN」については2021/10/31以降、一部の機能が使えなくなるため非推奨となっておりますので、ご注意ください。

設定項目

今回設定した内容を記載します。AWS設定は基本CLIコマンドになってます。GCPはマネジメントコンソールでの設定になってますが、 gcloud コマンドも記載してます。

基本的には、先ほどご紹介したVPN接続設定の記事のパターン3に沿って設定していただければOKです。設定項目が間違えやすいのでご注意ください。

一部記事と違う点があります。

  • IKE version: IKEv2 を使用

AWS設定 (1)

マネジメントコンソール上の操作内容は省略いたしますが、設定に使用したAWS CLIコマンドを掲載いたしますので、ご参考ください。

仮想プライベートゲートウェイ作成

aws ec2 create-vpn-gateway --type ipsec.1 --tag-specifications 'ResourceType=vpn-gateway,Tags=[{Key=Name,Value=aws-vpn-test-vgw}]'
#=> VpnGatewayId: vgw-00f0614bc7b0953d4

VGWをVPCにアタッチ

作成した仮想プライベートゲートウェイをVPCにアタッチします。

aws ec2 attach-vpn-gateway --vpc-id vpc-028bdb0ee3a9213b4 --vpn-gateway-id vgw-00f0614bc7b0953d4

ルート伝播設定

privateサブネットに関連づけられているルートテーブルにて、ルート伝播を有効化しておきます。

aws ec2 enable-vgw-route-propagation --gateway-id vgw-00f0614bc7b0953d4 --route-table-id rtb-0bc6e62228e1012cb

マネジメントコンソール上では、privateサブネットに関連付けられているルートテーブルに、以下のようにルート伝播が有効化されていることが確認できます。

ここで一旦GCPの作業に移ります。

GCP設定 (1)

ファイアウォールルール作成

AWS側からの通信を許可するファイアウォールルールを作成します。

[VPCネットワーキング] ⇒ [VPCネットワーキング] ⇒ [ファイアウォール]にて、「ファイアウォールルールを作成」をクリック。

  • ファイアウォールルール名: aws-vpn-test-fw-rule
  • ログ: オフ (default)
  • ネットワーク: aws-vpn-test-vpc
  • 優先度: 1000
  • トラフィックの方向: 上り
  • 一致したときのアクション: 許可
  • ターゲット: ネットワーク上のすべてのインスタンス
  • ソースフィルタ: IP範囲
  • ソースIPの範囲: 10.128.0.0/20 (AWSのVPC CIDR)
  • プロトコルとポート: すべて許可

gcloud compute --project=<プロジェクト名> firewall-rules create aws-vpn-test-fw-rule --direction=INGRESS --priority=1000 --network=aws-vpn-test-vpc --action=ALLOW --rules=all --source-ranges=10.128.0.0/20

Cloud Routerの作成

[ハイブリッド接続] ⇒ [Cloud Router] ページへ遷移し、「ルーターを作成」をクリックします。

  • 名前: aws-vpn-test-connect-aws-router
  • ネットワーク: aws-vpn-test-vpc
  • リージョン: asia-northeast1
  • Google ASN: 65000
  • BGPピアキープアライブの間隔: なし (default: 20)
  • アドバタイズされたルート:
    • Cloud Routerに表示されるすべてのサブネットにアドバタイズ (デフォルト)

gcloud compute routers create aws-vpn-test-connect-aws-router --project=<プロジェクト名> --region=asia-northeast1 --network=aws-vpn-test-vpc --asn=65000

VPNの作成

コマンドの出力がなかったので、 gcloud コマンドの内容は以下のページの内容を当てはめてみました。

[ハイブリッド接続] ⇒ [VPN]ページへ遷移し、「VPN接続を作成」をクリックします。 (すでにVPN接続作成済の場合は「VPN接続ウィザード」をクリック)

最初の画面では、以下を選択します。

  • VPNオプション: 高可用性 (HA) VPN

Cloud HA VPN ゲートウェイの作成

  • VPNゲートウェイの名前: aws-vpn-test-vgw
  • ネットワーク: aws-vpn-test-vpc
  • リージョン: asia-northeast1
  • 「作成して続行」をクリック

作成すると、2つのインタフェースが作成されます。

インタフェースのIPアドレスをメモし、このページを閉じずにAWS側にてVPN接続設定を行います。

0 : xx.xx.xx.xx

1 : yy.yy.yy.yy

gcloud コマンドだと以下の通りです。

gcloud compute vpn-gateways create aws-vpn-test-vgw \
    --network=aws-vpn-test-vpc \
    --region=asia-northeast1

一旦この画面のまま、AWS設定を行います。

AWS設定 (2)

ここからはGCPのVPN接続設定を終えてIPアドレスを2つ付与されてからの作業になります。

VPN接続設定

サイト間のVPN接続を2つ作成します。 GCPにて、Cloud HA VPNゲートウェイを作成すると、以下のようなIPアドレスが2つ作成されます。

0 : xx.xx.xx.xx

1 : yy.yy.yy.yy

これを使って、VPN接続を作成します。

VPN接続 (1つ目)

  • 名前タグ: aws-vpn-test-vpn-connection-1
  • ターゲットゲートウェイタイプ: 仮想プライベートゲートウェイ
  • 仮想プライベートゲートウェイ: aws-vpn-test-vgw
  • カスタマーゲートウェイ: 新規
    • IPアドレス: xx.xx.xx.xx
      • GCPのCloud HA VPNゲートウェイのインターフェイス0のIPアドレス
    • BGP ASN: 65000
      • GCPのCloud Routerで設定したGoogle ASNの値
    • 証明書ARN: 空欄
  • ルーティングオプション: 動的
  • トンネル内部IPバージョン: IPv4

他、デフォルトでOKです。

CLI上ではまずカスタマーゲートウェイを作成してから、VPN接続を作成します。

## カスタマーゲートウェイ作成 (1)
# カスタマーゲートウェイの名前: aws-vpn-test-customer-gw-1
aws ec2 create-customer-gateway --type ipsec.1 --bgp-asn 65000 --public-ip xx.xx.xx.xx --tag-specifications 'ResourceType=customer-gateway,Tags=[{Key=Name,Value=aws-vpn-test-customer-gw-1}]'
#=> CustomerGatewayId: cgw-00510ac1ba2c47769
## VPN接続作成 (1)
aws ec2 create-vpn-connection --type ipsec.1 --customer-gateway-id cgw-00510ac1ba2c47769 --vpn-gateway-id vgw-00f0614bc7b0953d4 --tag-specifications 'ResourceType=vpn-connection,Tags=[{Key=Name,Value=aws-vpn-test-vpn-connection-1}]'
#=> VpnConnectionId: vpn-01abcf950efef52aa

VPN接続を作成したら、「設定のダウンロード」をしておきます。

  • ベンダー: Generic
  • プラットフォーム: Generic
  • ソフトウェア: Vendor Agnostic
  • Ike Version: ikev2
## 'jq -r' で、JSON Valueのエスケープ文字をそのまま標準出力させる
aws ec2 get-vpn-connection-device-sample-configuration --vpn-connection-id vpn-01abcf950efef52aa --vpn-connection-device-type-id 9005b6c1 --internet-key-exchange-version ikev2 | jq -r ".VpnConnectionDeviceSampleConfiguration" > vpn-conn1.txt

なお、AWS CLI v2 のバージョンが古いと、 get-vpn-connection-device-* のコマンドが動作しないので、 CLI v2のバージョンを2.2.40 以上にアップデートしておきましょう。

Missing get-vpn-connection-device-* commands · Issue #6432 · aws/aws-cli

また、 --vpn-connection-device-type-id は以下のコマンドで確認できます。

aws ec2 get-vpn-connection-device-types --query="VpnConnectionDeviceTypes[?Vendor=='Generic']"
[
    {
        "VpnConnectionDeviceTypeId": "9005b6c1",
        "Vendor": "Generic",
        "Platform": "Generic",
        "Software": "Vendor Agnostic"
    }
]

VPN接続 (2つ目)

  • 名前タグ: aws-vpn-test-vpn-connection-2
  • ターゲットゲートウェイタイプ: 仮想プライベートゲートウェイ
  • 仮想プライベートゲートウェイ: aws-vpn-test-vgw
  • カスタマーゲートウェイ: 新規
    • IPアドレス: yy.yy.yy.yy
      • GCPのCloud HA VPNゲートウェイのインターフェイス1のIPアドレス
    • BGP ASN: 65000
      • GCPのCloud Routerで設定したGoogle ASNの値
    • 証明書ARN: 空欄
  • ルーティングオプション: 動的
  • トンネル内部IPバージョン: IPv4

他、デフォルトでOKです。

## カスタマーゲートウェイ作成 (2)
# カスタマーゲートウェイの名前: aws-vpn-test-customer-gw-2
aws ec2 create-customer-gateway --type ipsec.1 --bgp-asn 65000 --public-ip yy.yy.yy.yy --tag-specifications 'ResourceType=customer-gateway,Tags=[{Key=Name,Value=aws-vpn-test-customer-gw-2}]'
#=> CustomerGatewayId: cgw-0f08e99328b991535
## VPN接続作成 (2)
aws ec2 create-vpn-connection --type ipsec.1 --customer-gateway-id cgw-0f08e99328b991535 --vpn-gateway-id vgw-00f0614bc7b0953d4 --tag-specifications 'ResourceType=vpn-connection,Tags=[{Key=Name,Value=aws-vpn-test-vpn-connection-2}]'
#=> VpnConnectionId: vpn-0b2c5dbe570b7a4db

VPN接続を作成したら、こちらも「設定のダウンロード」をしておきます。

  • ベンダー: Generic
  • プラットフォーム: Generic
  • ソフトウェア: Vendor Agnostic
  • Ike Version: ikev2
aws ec2 get-vpn-connection-device-sample-configuration --vpn-connection-id vpn-0b2c5dbe570b7a4db --vpn-connection-device-type-id 9005b6c1 --internet-key-exchange-version ikev2 | jq -r ".VpnConnectionDeviceSampleConfiguration" > vpn-conn2.txt

2つの設定ファイルを元に、GCP側の設定を再開します。

GCP設定 (2)

以下の画面から再開します。VPNトンネルの追加を行います。

なお、AWSの各VPN接続につき2つのVPNトンネルができています。今回設定する「パターン3」では各VPN接続につき1つのトンネルを使用して、GCPのHA VPNと接続することになります。

先ほどダウンロードした各VPN接続設定ファイルには2つのVPNトンネル設定が記述されており、今回は各設定ファイルにある「 IPSec Tunnel #1 」しか使いません。設定の際には間違えないように注意しましょう。

VPNトンネルの追加

VPNトンネルを追加する際に、まず初めにピアVPNゲートウェイを追加します。

  • ピアVPNゲートウェイ: オンプレミスまたは非Google Cloud
  • ピアVPNゲートウェイの名前: 「新しいピアVPNゲートウェイを作成する」をクリック
    • 名前: aws-vpn-test-peer-vgw
    • ピアVPNゲートウェイインターフェイス
      • 2つのインターフェイス
        • インターフェイス0のIPアドレス: aa.aa.aa.aa
          • AWS側のVPN connection 1の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface Configuration の Outside IP Addresses: Virtual Private Gateway
        • インターフェイス1のIPアドレス: bb.bb.bb.bb
          • AWS側のVPN connection 2の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのOutside IP Addresses: Virtual Private Gateway
    • 「作成」をクリック

ピアVPNゲートウェイを作成すると、以下の画面になるので、設定を続けます。

  • 高可用性: VPNトンネルのペアを作成する
  • ルーティングオプション: 動的 (BGP) (変更不可)
  • Cloud Router: aws-vpn-test-connect-aws-router

各「VPNトンネル (未構成)」をクリックして、2つのVPNトンネルの設定を行います。

  • VPNトンネル:
    1. 1つ目のVPNトンネル
      • 関連づけられているCloud VPNゲートウェイインターフェイス: xx.xx.xx.xx
        • GCPのVPNゲートウェイのインターフェイス0と、AWS側VPN connection 1の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのOutside IP Addresses: Customer Gateway と一致していること
      • 関連づけられているピアVPNゲートウェイインターフェイス: aa.aa.aa.aa
        • AWS側VPN connection 1の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのOutside IP Addresses: Virtual Private Gateway と一致していること
      • 名前: aws-vpn-test-vpn-tunnel-1
      • IKEバージョン: IKEv2
      • IKE事前共有キー:
        • AWS側VPN connection 1の設定ファイルの中から、IPSec Tunnel #1 > #1: Internet Key Exchange ConfigurationのPre-Shared Key を入力
    2. 2つ目のVPNトンネル
      • 関連づけられているCloud VPNゲートウェイインターフェイス: yy.yy.yy.yy
        • GCPのVPNゲートウェイのインターフェイス1と、AWS側VPN connection 2の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのOutside IP Addresses: Customer Gateway と一致していること
      • 関連づけられているピアVPNゲートウェイインターフェイス: bb.bb.bb.bb
        • AWS側VPN connection 2の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのOutside IP Addresses: Virtual Private Gateway と一致していること
      • 名前: aws-vpn-test-vpn-tunnel-2
      • IKEバージョン: IKEv2
      • IKE事前共有キー:
        • AWS側VPN connection 2の設定ファイルの中から、IPSec Tunnel #1 > #1: Internet Key Exchange ConfigurationのPre-Shared Key を入力

2つのVPNトンネルを設定したら、「作成して続行」をクリックします。

なお、 gcloud コマンドでは以下のようになります。

## ピアVPNゲートウェイの作成
gcloud compute external-vpn-gateways create aws-vpn-test-peer-vgw \
    --interfaces 0=aa.aa.aa.aa,1=bb.bb.bb.bb
## VPNトンネル(1)の作成
gcloud compute vpn-tunnels create aws-vpn-test-vpn-tunnel-1 \
    --peer-external-gateway=aws-vpn-test-peer-vgw \
    --peer-external-gateway-interface=0  \
    --region=asia-northeast1 \
    --ike-version=2 \
    --shared-secret=<Pre-Shared Key> \
    --router=aws-vpn-test-connect-aws-router \
    --vpn-gateway=aws-vpn-test-vgw \
    --interface=0
## VPNトンネル(2)の作成
gcloud compute vpn-tunnels create aws-vpn-test-vpn-tunnel-2 \
    --peer-external-gateway=aws-vpn-test-peer-vgw \
    --peer-external-gateway-interface=1  \
    --region=asia-northeast1 \
    --ike-version=2 \
    --shared-secret=<Pre-Shared Key> \
    --router=aws-vpn-test-connect-aws-router \
    --vpn-gateway=aws-vpn-test-vgw \
    --interface=1

BGPセッションの構成

AWSとGCP間でルーティング情報をやり取りするためのBGPセッションを設定します。 BGPセッションの構成は、Cloud Routerに設定されます。

各トンネルのBGPセッションの「設定」をクリックして、設定を進めます。

tunnel-1の構成

  • 名前: aws-vpn-test-bgp-1
  • ピアASN: 64512
    • AWS側VPN connection 1の設定ファイルの中から、IPSec Tunnel #1 > #4: Border Gateway Protocol (BGP) ConfigurationのBGP Configuration Options: Virtual Private Gateway ASN
  • アドバタイズされたルートの優先度 (MED): 空欄
  • Cloud RouterのBGP IP: pp.pp.pp.pp
    • AWS側VPN connection 1の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのInside IP Addresses - Customer Gateway
  • BGPピアIP: ii.ii.ii.ii
    • AWS側VPN connection 1の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのInside IP Addresses - Virtual Private Gateway
  • BGPピア: 有効

あとはデフォルトでOKです。

tunnel-2の構成

  • 名前: aws-vpn-test-bgp-2
  • ピアASN: 64512
    • AWS側VPN connection 2の設定ファイルの中から、IPSec Tunnel #1 > #4: Border Gateway Protocol (BGP) ConfigurationのBGP Configuration Options: Virtual Private Gateway ASN
  • アドバタイズされたルートの優先度 (MED): 空欄
  • Cloud RouterのBGP IP: qq.qq.qq.qq
    • AWS側VPN connection 2の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのInside IP Addresses - Customer Gateway
  • BGPピアIP: jj.jj.jj.jj
    • AWS側VPN connection 2の設定ファイルの中から、IPSec Tunnel #1 > #3: Tunnel Interface ConfigurationのInside IP Addresses - Virtual Private Gateway
  • BGPピア: 有効

あとはデフォルトでOKです。

2つのBGPセッションを構成したら「BGP構成を保存」をクリックします。

なお、 gcloud コマンドだと以下の通りです。

## Tunnel1のBGPセッション用のインターフェイスをCloud Routerに追加
# InterfaceName: if-aws-vpn-test-bgp-1
gcloud compute routers add-interface aws-vpn-test-connect-aws-router \
    --interface-name=if-aws-vpn-test-bgp-1 \
    --mask-length=30 \
    --vpn-tunnel=aws-vpn-test-vpn-tunnel-1 \
    --ip-address=pp.pp.pp.pp \
    --region=asia-northeast1
## Tunnel1のBGPセッション構成をCloud Routerに設定
gcloud compute routers add-bgp-peer aws-vpn-test-connect-aws-router \
    --peer-name=aws-vpn-test-bgp-1 \
    --peer-asn=64512 \
    --interface=if-aws-vpn-test-bgp-1 \
    --peer-ip-address=ii.ii.ii.ii \
    --region=asia-northeast1
## Tunnel2のBGPセッション用のインターフェイスをCloud Routerに追加
# InterfaceName: if-aws-vpn-test-bgp-2
gcloud compute routers add-interface aws-vpn-test-connect-aws-router \
    --interface-name=if-aws-vpn-test-bgp-2 \
    --mask-length=30 \
    --vpn-tunnel=aws-vpn-test-vpn-tunnel-2 \
    --ip-address=qq.qq.qq.qq \
    --region=asia-northeast1
## Tunnel2のBGPセッション構成をCloud Routerに設定
gcloud compute routers add-bgp-peer aws-vpn-test-connect-aws-router \
    --peer-name=aws-vpn-test-bgp-2 \
    --peer-asn=64512 \
    --interface=if-aws-vpn-test-bgp-2 \
    --peer-ip-address=jj.jj.jj.jj \
    --region=asia-northeast1

確認

VPNトンネルのステータスが「確立済み」であればOKです。 すぐに確立済みにならないので、しばらく時間を置いてから再度確認してみてください。

AWS側確認

VPN接続が確立済みであれば、AWS側の各接続のトンネル2つの内1つのステータスが「アップ」となります。

またprivateサブネットのルーティングテーブルには、GCPのサブネットが自動的に追加されています。

EC2を起動してSSHログインし、GCPのVMインスタンスの内部IPアドレス宛にPingを打ってみます。

## EC2にログインして実行。
## GCPのVMインスタンスの内部IPアドレス(今回は10.146.0.2)宛にpingを打つ。
ping 10.146.0.2
PING 10.146.0.2 (10.146.0.2) 56(84) bytes of data.
64 bytes from 10.146.0.2: icmp_seq=1 ttl=63 time=111 ms
64 bytes from 10.146.0.2: icmp_seq=2 ttl=63 time=108 ms
64 bytes from 10.146.0.2: icmp_seq=3 ttl=63 time=107 ms
64 bytes from 10.146.0.2: icmp_seq=4 ttl=63 time=106 ms
^C
--- 10.146.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms

なお、GCPのVMインスタンスからAWSのEC2へのpingはAWSのセキュリティグループにICMPのインバウンドを許可していないため、繋がりません。

確認したい場合は、以下のようにセキュリティグループにICMPのインバウンドを許可するルールを追加しましょう。

aws ec2 authorize-security-group-ingress --group-id sg-039e68d4778071712 --ip-permissions IpProtocol=icmp,FromPort=-1,ToPort=-1,IpRanges='[{CidrIp=10.146.0.0/24}]'

接続がうまくいかない時

接続がうまくいかない時は以下の部分を確認して、間違っている場合は修正しましょう。

  • AWS/GCPのVPN設定を確認する
    • 特にGCP側はAWS側の設定ファイルを使用してIPアドレスやPre-Shared Keyを設定するので、間違えやすいです。設定ファイル内に2つのトンネルの設定が入っているため、誤ってて別のトンネルの設定を登録しがちなので、再度確認しましょう。
  • GCP側のファイアウォール設定を確認する
    • IP範囲を間違えて、AWS側の通信を拒否していないか、確認しましょう。
  • GCP側のVMインスタンスのネットワーク設定を確認する
    • VMインスタンスのネットワークインターフェイスが default VPCに設置されていると、AWSからのVPN通信が届きません。VMインスタンスのネットワークインターフェイスが今回使用するVPC (aws-vpn-test-vpc) とサブネット (aws-vpn-test-asne1-subnet-1) になっているか、確認しましょう。

まとめ

今回はCLIベースでの構築ができるようにAWS/GCPでCLIコマンドを用意しました。

Webコンソール上での操作やCfn/CDKなどのツールに慣れている方は適宜読み替えていただければと思います。次はPrivate Service ConnectエンドポイントとDNS設定をして、EC2からBigQueryへアクセスするための作業を行います。