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-10-16 11.22.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/2383be50-875c-6857-0567-18e36f47f5d3.png)


#2020/06/18 追記
Cloud Runから外部へのHTTPリクエストも、固定IP化できそう。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おっ gcloud alpha run deploy の方には --vpc-egress オプションが生えている<a href="https://t.co/mtAhVfYj0D">https://t.co/mtAhVfYj0D</a></p>&mdash; _ (@apstndb) <a href="https://twitter.com/apstndb/status/1273507657219928065?ref_src=twsrc%5Etfw">June 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#やりたいこと
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

#手順メモ

##関数を作成
<img width="1552" alt="スクリーンショット 2020-02-11 0.27.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/a8add7f7-241e-e97a-c131-64bdf10d7cab.png">

```go: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:go.mod
module example.com/sample

go 1.11
```

##GCFを実行してみる1
`107.178.234.80`でアクセスしている。これは固定IPではない。
![スクリーンショット 2020-02-20 0.04.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/515e37a3-026b-a833-e109-303fb2f580d8.png)


##VPC、サブネットを作成
サブネットはここでは`192.168.0.0/24`に設定。（後でこれと被らない範囲を指定する場面がある）
<img width="1552" alt="スクリーンショット 2020-02-11 0.47.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/8b373b2a-eb93-845b-9d07-d4b172740a85.png">

##サーバーレスVPCアクセスコネクタを作成
初回はエラーになる事がある。→Serverless VPC Access APIを有効化する必要がある。
![スクリーンショット 2020-02-20 0.08.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/bd0b90cc-dbd9-45ee-fa6b-ff956f99a2b9.png)

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

![スクリーンショット 2020-02-20 0.12.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/a0a0564c-b262-170a-9acd-63322c25c0c4.png)

必要事項を入力して作成。
IP範囲はここでは`192.168.2.0/24`に設定。
最小スループットと最大スループットはそれぞれ200、300が下限。変えられそうに見えるけどバリデーションでエラーになり、最小スループットは200〜。最大スループットは下限より大きい値で100の倍数を求められる。
![スクリーンショット 2020-02-20 0.14.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/e734460d-fc66-1d02-bc90-dbfbd4abc491.png)

作成完了したらGCFに戻ってコネクタの設定を行う。
`すべてのトラフィックを VPC コネクタ経由でルーティングする`を選択するのが大事。これによって必ずVPCコネクタ経由のリクエストになる。これをしないと先ほど実行してみた際の外部IPで出ていってしまう。
![スクリーンショット 2020-02-20 0.18.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/dd34fad4-338d-8627-0175-85c38b720429.png)

##GCFを実行してみる2
リクエストがVPCへルーティングされ、そこから外へ出られないのでエラーとなる。（想定通り）
![スクリーンショット 2020-02-20 0.29.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/ed7b56c3-4c0c-f666-e4ce-1efc7b0ee080.png)


##Cloud NATを作成
VPCから外へ出るためのCloud NATを作成する。ルーターも合わせて作成する。
![スクリーンショット 2020-02-20 0.30.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/046e9207-80e3-5a46-e9c8-422f2dd9a42e.png)
![スクリーンショット 2020-02-20 0.31.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/0db2b5e6-d858-03dd-1d97-198e5b7f96c0.png)

NATアドレスは手動を選択し、静的IPを作成して割り当てる。
![スクリーンショット 2020-02-20 0.33.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/de8a185e-5f93-cd2a-d570-326cc2b7b2c8.png)

静的IPが割り当てられた。これでCloud NATを作成する。
![スクリーンショット 2020-02-20 0.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/503797af-7278-d16e-1db9-7dbccbc3f0fe.png)

##GCFを実行してみる3
Cloud NATを作成した際に割り当てた静的IP`35.200.133.233`で接続できている。
このIPアドレスをサービスのホワイトリストに入れてもらえばOK。
![スクリーンショット 2020-02-20 0.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/bbc3a92b-880b-ecc4-b1d9-39ffabf9f7a7.png)