GCFから外部へのHTTPリクエストを固定IPにする


2020/10/16 追記

Cloud Runから外部へのHTTPリクエストも、固定IP化できるようになりました。
https://cloud.google.com/run/docs/release-notes#October_13_2020
https://cloud.google.com/run/docs/configuring/connecting-vpc?hl=en#egress

2020/06/18 追記

Cloud Runから外部へのHTTPリクエストも、固定IP化できそう。

やりたいこと

GCFから、ホワイトリストに登録されたIPアドレスからのみリクエストを許可するサービスへアクセスしたい。

使うもの

GCF、VPC、サーバーレスVPCアクセス、Cloud NAT

公式ドキュメント

この辺に書いてある。
https://cloud.google.com/functions/docs/networking/network-settings#route-egress-to-vpc
https://cloud.google.com/nat/docs/using-nat#specify_subnet_ranges_for_nat

費用

https://cloud.google.com/functions/pricing
https://cloud.google.com/vpc/docs/configure-serverless-vpc-access#pricing
https://cloud.google.com/nat/pricing
https://cloud.google.com/compute/network-pricing#ipaddress

手順メモ

関数を作成

functions.go
package p

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

// Sample print global ip address.
func Sample(w http.ResponseWriter, r *http.Request) {
    resp, err := http.Get("http://httpbin.org/ip")
    if err != nil {
        fmt.Println(err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
go.mod
module example.com/sample

go 1.11

GCFを実行してみる1

107.178.234.80でアクセスしている。これは固定IPではない。

VPC、サブネットを作成

サブネットはここでは192.168.0.0/24に設定。(後でこれと被らない範囲を指定する場面がある)

サーバーレスVPCアクセスコネクタを作成

初回はエラーになる事がある。→Serverless VPC Access APIを有効化する必要がある。

以下のURLを直接叩くとAPIを有効化する画面に飛べる。[your-projectid]は読み替えること。普通にAPIのメニューの方から行ってもOK。
https://console.cloud.google.com/networking/connectors/add?project=[your-projectid]

必要事項を入力して作成。
IP範囲はここでは192.168.2.0/24に設定。
最小スループットと最大スループットはそれぞれ200、300が下限。変えられそうに見えるけどバリデーションでエラーになり、最小スループットは200〜。最大スループットは下限より大きい値で100の倍数を求められる。

作成完了したらGCFに戻ってコネクタの設定を行う。
すべてのトラフィックを VPC コネクタ経由でルーティングするを選択するのが大事。これによって必ずVPCコネクタ経由のリクエストになる。これをしないと先ほど実行してみた際の外部IPで出ていってしまう。

GCFを実行してみる2

リクエストがVPCへルーティングされ、そこから外へ出られないのでエラーとなる。(想定通り)

Cloud NATを作成

VPCから外へ出るためのCloud NATを作成する。ルーターも合わせて作成する。

NATアドレスは手動を選択し、静的IPを作成して割り当てる。

静的IPが割り当てられた。これでCloud NATを作成する。

GCFを実行してみる3

Cloud NATを作成した際に割り当てた静的IP35.200.133.233で接続できている。
このIPアドレスをサービスのホワイトリストに入れてもらえばOK。