【GCP】cloud runを外部アクセスから守るためのcloud load balancing設定(cloud domains使用)

## 概要
cloud runを使ってアプリのバックエンドを構築しており、外部サービスのweb hookを受けつることになりました。

runのセキュリティをガバガバにしたままだと怖くて眠れないのでcloud armerでバリデーションして安心して眠れるようにするためにcloud load balancingを設定したのでその共有です


## 大まかな手順
1. cloud runを構築
2. cloud domainsで独自ドメイン取得
3. cloud load balancingを設定
    a. cloud domainsで契約したドメインのレコードにIPを登録

コツ: 一発で全クリできる天才以外は、ハマったときにどこが原因か分からなくなるので1サービスづつ丁寧に疎通を確認した方が吉です

### cloud runの構築
#### → 「サンプルコンテナでテスト」というボタンをクリック
dockerのイメージやらgcloudでのイケてるデプロイやらの解説をする気力がないので今回は、cloud runコンソール画面の「サービスを作成」ボタンから「サンプルコンテナでテスト」という神ボタンから疎通確認用のrunを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/e428b937-9047-e96e-a413-5977e25d898b.png)

一つだけ注意点がありこの疎通確認用のコンテナを作るときは、「認証」の箇所で「未認証の呼び出しを許可」をクリックしてセキュリティをガバガバにしてください（本番ではダメ!ゼッタイ）
![スクリーンショット 2024-01-07 20.10.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/920b8369-2606-6f0b-09d9-f7fbac2fe4ea.png)

python使ってる同士は、jupyterから下記実行したら確認できます。ステータスコードが200だったらrunはおｋです！

```python
import requests
# 僕のが作ったサンプル: https://hello-z2bmqu5rca-uc.a.run.app
run_url = f"{今回作成したrunのurl}"  
res = requests.get(run_url)

assert res.status_code == 200, "なんか間違えてるよ"
print("status_code:", res.status_code)
print(res.text[:100])
```

### cloud domainsで独自ドメイン取得
特にこだわりがなければ、同じサービスなのでレコード追加時などにレコメンドが出てきたりして楽ちんです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/aac8409f-a801-61fc-473e-ccc468e8b11a.png)
上記は例ですが、基本デフォルトのまま進行して大丈夫です

### cloud load balancingの設定
コンソールの画面上部の「ロードバランサの作成」ボタンから作ります
![スクリーンショット 2024-01-07 20.24.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/22d1039d-ef6c-0990-391b-9e3c0f455177.png)

「アプリケーション ロードバランサ（HTTP/S）」の項目の「構成を開始」をクリック
![スクリーンショット 2024-01-07 20.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/3913d38d-b3ac-6860-83d9-8896f7d09449.png)

ここはデフォルトでおｋ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/2c5f4a03-14ce-8fa1-d056-04412551049c.png)

フロントエンドの構成のところは、「今回はrunでバックだけやけん、いらんやん」と思うけどここ飛ばしたら利用できないの刑になります。

プロトコルは「HTTPS」を選択（最初は「HTTP」）して証明書のところで「新しい証明書を作成」をクリック
![スクリーンショット 2024-01-07 20.27.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/f3b57c00-e860-6a77-c094-bc83ca0901b0.png)

名前とか適当に決めて作成モードで「Googleマネージドの証明書を作成する」をクリックして、下の方の「ドメイン」にcloud domainsで契約したドメインを入力してあとはデフォルトでおｋ
![スクリーンショット 2024-01-07 20.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/d41c2748-c12a-cecc-f6c3-25b34dd36393.png)

次はバックエンドの構成で、「バックエンドサービスを作成」をクリック
![スクリーンショット 2024-01-07 20.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/f3d2391b-b3e8-75c1-4b45-facd2f2c9ce8.png)

バックエンドタイプを「サーバーレス ネットワーク エンドポイント グループ」にして（最初は「インスタンス グループ」）、新しいバックエンドのところは、最初にこしらえたcloud runを選択
![スクリーンショット 2024-01-07 20.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/f35dc7c8-2e4a-b6ad-0a6c-5e205693c543.png)

あとは画面下部の作成をクリックして初期作成は終わりです
その後ロードバランシグのトップ画面で今回作ったロードバランシグを選択します
![スクリーンショット 2024-01-07 20.38.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/509724e4-fd89-0f10-0277-673d02cb50ff.png)

フロントエンドの箇所の「HTTPS」の欄のよこのIPを覚えます（cloud domainsじゃない人はコピー）
![スクリーンショット 2024-01-07 20.39.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/665e4ebf-ea73-bfdc-00d5-bc7cd2176005.png)

cloud DNSサービス（cloud domainsではないですよ！）のドメイン詳細画面に行きます
![スクリーンショット 2024-01-07 20.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/0eeedb07-1f94-65b3-dc22-c76c4f3ed5a2.png)


詳細画面の中央付近の「標準を追加」をクリック
![スクリーンショット 2024-01-07 20.44.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/e0a756d1-503f-4f0d-a4d1-b862d39ffbfb.png)


DNS名空白で、他の選択項目をデフォルト（僕のスクショ通り）で「IP」アドレスの選択から先程、覚えたIPを選択して「作成」でおｋ
![スクリーンショット 2024-01-07 20.46.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/0b2b5c34-9636-bf88-f8d0-cdd5aacc957d.png)

別のドメインサービスでドメイン契約した方は、そのサービスのDNS設定画面からAレコードタイプでDNS名には「@」を入れて今回のIPを入力したらいけます。ちなみにポート番号は不要です
```shell
# ↓の「:433」がポート番号
192.0.0.11:443
```

あとは、お茶かコーヒーを入れてタイマーを30分設定してYouTubeでも見ながら、待機して30分くらいたったら、ロードバランサの詳細画面に戻ってきて「証明書」の箇所をクリックします
![スクリーンショット 2024-01-07 20.52.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/380b128b-e212-2eb3-86b2-ac6caa09f2bd.png)

スクショのように、「ACTIVE」となっていたら、成功でそれ以外は失敗になります。
![スクリーンショット 2024-01-07 20.54.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/96c6300c-60bb-d5d4-e9a6-24b4eafe9935.png)

失敗になる原因としては、下記が考えられます。
特に、「IPの前後に空白が入るなんてありえない」と考えると思いますが過信はNGです
- 変なドメインサービスの利用
- DNS登録時にIPの前後に空白が入ってる
- 運が悪い
- 日頃の行いが悪い

## おまけ
ここまで設定したら、cloud armerも設定したいと思うので、いくつか僕が知っていることを共有します。設定自体は簡単なので省略します

部分一致で一部のリクエストを受け付けたり除外したりするときの構文
```shell
request.path.matches(r"/index.*")
```
右側の優先度の数値が小さい順にバリデーションされて該当するアクションがあったら後続のアクションは処理されないです。

![スクリーンショット 2024-01-07 21.00.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121605/4d4d77c0-d001-69fa-6a34-26305cdb77b4.png)

バックのテストの続きしないと怒られるので本日はこのへんで終わり^^