Google Cloud Functions -> Elastic Cloud を Private Service Connect 経由で接続するには

# 最初に

Elastic Cloud と Google Cloud のリソース間の通信をセキュアにするために、 Private Service Connect (PSC) という Google Cloud 機能があります。そこまで Google Cloud を触った経験がないため、その勉強も兼ねて、Cloud Functions から Elastic Cloud に PSC 経由でリクエストできることを確認するために行った手順のメモを残しておきます。

:::note warn
各々のサービスは進化が早いので厳密な手順を残すというとより、キーとなった設定等を残すためのメモとなります。 2024年4月現在試したものですので、最新の情報に関しては公式のドキュメント等をご参照ください。あと、今回はすべて GUI を使って設定しています。自動化されたい方の参考にはあまりならないかもしれません。
:::

# 手順

主な手順は下記の通りです（E = Elastic Cloud, G = Google Cloud）

- [E] Elastic Cloud のデプロイメントを作成
- [G] VPC network の作成
- [G] Private Service Connect の作成
- [G] DNS の作成
- [E] Traffic Filter の作成・設定
- [G] Cloud Functions の作成・設定
- [G] テスト

途中まではこちらの Elastic Cloud の Private Service Connect のドキュメントをベースに作業しています。
https://www.elastic.co/guide/en/cloud/current/ec-traffic-filtering-psc.html


## [E] Elastic Cloud のデプロイメントを作成

作成にあたって、 Google Cloud で使う想定のリージョンまで同じである必要があります。日本の場合は Tokyo (asia-northeast1) を使います。
https://www.elastic.co/guide/en/cloud/current/ec-create-deployment.html


:::note warn
取り急ぎ試す場合は、デプロイメント作成時に表示されるパスワードを残しておいてください。
:::

## [G] VPC network の作成

Google Cloud で VPC Network を作成します。先ほどの手順の通り、作成するリージョンにご注意ください。

:::note warn
手順的にはのちほど作成しますが、専用 subnet の作成等が必要になるため、このタイミングで Serverless VPC Access を作成しても大丈夫だと思います。空きのある /28 のアドレス空間を把握しておいてください。
:::
    
## [G] Private Service Connect の作成

https://www.elastic.co/guide/en/cloud/current/ec-traffic-filtering-psc.html
こちらのドキュメントを参照しつつ、適切にPSC を作成していきます。
ここで Internal IP を作成する必要があります。

PSC Connection ID も後ほど使うため、メモしておきます。


## [G] DNS の作成

先ほど作った PSC のエンドポイントに向けて、 Private Zone DNS name を向けるためのDNSを作成します。リージョン毎にドメインが違うので、ドキュメントからテストスニペットをコピペすると、 URL が違って正しく動かない可能性があるので注意してください。

Private DNS を VPC network と紐づけます（DNS 作成で指定可能）。

最後に Internal IP とワイルドカード（*) で新しい A レコードを作成します。


## [E] Traffic Filter の作成・設定

Elastic Cloud の Traffic Filter を作成して、それをデプロイメントに紐づけます。
https://www.elastic.co/guide/en/cloud/current/ec-traffic-filtering-psc.html#ec-psc-create-traffic-filter-psc-rule-set
https://www.elastic.co/guide/en/cloud/current/ec-traffic-filtering-psc.html#ec-psc-associate-traffic-filter-psc-rule-set

ネットワーク周りの設定はいったん以上です。Google で VPC に紐づくリソースであればこの時点で通信できるようになっているかと思われます。かわりに、 Elastic Cloud の持っているパブリックなエンドポイントはアクセスできないようになっているはずです。

アクセスしたらこのようなレスポンスが返るはずです。

```
{
"ok": false,
"message": "Forbidden"
}
```

## [G] Cloud Functions の作成・設定

Cloud Functions を作成します。詳細は割愛しますが、重要なポイントは、`Runtime, build, connections and security settings` > `Connections` の設定にある `Egress Settings` を設定する必要があります。


:::note warn
注意点として、コード編集画面で "RUN TEST" を試しても　Egress settings 反映されない（？間違っていたらごめんなさい）ようで、疎通できないレスポンス(`{"message": "Forbidden"}`) が返ります。疎通のテストは一度デプロイを完了させてから行ってみてください。
:::

この画面で、新しく VPC connector を作成する必要があります。（前の手順ですでに作成している場合はそれを選択します）

今回使った取り急ぎのテストコード（python 3.12 を使っています。 requirements.txt に requests を追加しています）
{} で囲まれた2つの値は変更が必要です。`デプロイメントの名前` はデプロイメントの alias にあてはまります。ドキュメントにも記述がありますので必要であればご確認ください。
https://www.elastic.co/guide/en/cloud/current/ec-traffic-filtering-psc.html#ec-private-service-connect-enpoint-dns


```
import functions_framework
import requests

@functions_framework.http
def hello_http(request):
    url = "https://elastic:{DEPLOYMENTのパスワード}@{デプロイメントの名前}.es.psc.asia-northeast1.gcp.cloud.es.io:9243"

    response = requests.get(url)
    return response.text

```


# 最後に

取り急ぎ PSC が使えることを検証したく、せっかくやるなら手順を残しておく程度の記事になっていますが、Cloud Functions -> Elatsic Cloud で通信できることは確認できました。

何か参考になればとこちらにもシェアしています。