Cloud Run + Cloud SQL、セットアップ

## はじめに

この記事は、
　[Cloud Run + Cloud SQL, setup
](https://www.youtube.com/watch?v=cBrn5IM4mA8)という動画を参考に、『実際にやってみた』という記事になります。


## この記事で実施する事。
- `Cloud SQL` インスタンス を作成。
- `Cloud Run Service` をデプロイする。
- `Cloud Shell` を使用して、`Cloud SQL` インスタンスに接続する。
- `テーブル作成` と `データ挿入`
- `Cloud Run` にデプロイされたアプリを動かす。
- `Cloud SQL` にデータが挿入されたかを確認する。

以下はその必要となる大まかな構成になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/44814f53-8852-5698-87c7-f8689ca791c7.png)


## Google Cloud SQLについて噛み砕いて理解しておく。
<details><summary>Google Cloud SQL について噛み砕いた説明を以下にまとめます。</summary>
<p>

（Chat GPT）
フルマネージド型のリレーショナルデータベースサービス。
>Googleが管理してくれるため、ユーザーはサーバーの設定や
保守の心配をせずに、データを保存・管理を行うことができる。
>
>リレーショナルデータベース形式を採用しているため、
データは表形式で整理され、効率的に扱えます。

（Chat GPT）
Cloud SQLは、MySQL、PostgreSQL、およびSQL Serverをサポートし、
高可用性とセキュリティを備えたスケーラブルなインフラ上で運用されます。
>Cloud SQLは、MySQL、PostgreSQL、SQL Serverを
サポートする柔軟なデータベースサービスです。
>
>高可用性も備えており、サービスの停止時間が
極めて少なく、信頼性が高い。
>
>また、スケーラブルなインフラにより、データベースの
サイズを使用状況に応じて簡単に調整できます。
>
>これにより、ビジネスの成長や需要の
変化に柔軟に対応することが可能です。
>
>さらに、Googleによる厳重なセキュリティ対策により、
データの安全性も確保されています。

（Chat GPT）
Webアプリケーション、モバイルアプリ、
ゲーム、分析ツールなど様々な用途に適している。
>Cloud SQLは、Webアプリケーション、モバイルアプリ、ゲーム、
分析ツールなど、様々な用途に使えるデータベースサービスである。
>
>これは、インターネット上で動くさまざまなプログラムや
アプリケーションが、データを保存したり、
取得したりするために使えるということである。
>
>たとえば、オンラインショップのWebアプリケーションでは、
顧客の注文情報や商品データをCloud SQLに保存することが可能。
>
>モバイルアプリの場合は、ユーザーの設定や
進行状況を保存する為に使える。
>
>ゲームではプレイヤーのスコアやランキング情報、
分析ツールでは集めたデータの分析結果などを扱う際にも利用される。
>
>つまり、Cloud SQLは、インターネットを介して様々な種類の
アプリケーションでデータを扱うための汎用的で便利なツールである。

（Chat GPT）
利用者は、サーバーのメンテナンスや
アップデートなどの複雑なタスクを気にすることなく、
データベースインスタンスの簡単な拡張が可能です。
ただし、最適なパフォーマンスを得るためには、
データベースの設定やスキーマ設計に注意が必要である。
>Cloud SQLを使うと、利用者はサーバーのメンテナンスや
>アップデートといった複雑な作業を気にする必要がありません。
>
>つまり、サーバーが最新の状態に保たれ、常に良い状態で
動き続けるための面倒な作業はGoogleが全て行ってくれる。
>
>また、データベースのサイズを簡単に変更することができます。
>
>これは、アプリが人気になってユーザーが増えたり、
より多くのデータを扱うようになったりした時に、
データベースをスムーズに大きくすることも、
逆に小さくすることもできるということです。
>
>ただし、最高のパフォーマンスを得るためには、
データベースの設定やデータを整理するための
「スキーマ」と呼ばれる設計に注意が必要。
>
>これは、データベースを効率的に動かすために、
どのようにデータを整理しておくべきかを考えることを意味している。
>
>簡単に言えば、Cloud SQLはサーバーの面倒な管理を
気にせずに使え、必要に応じてデータベースのサイズを
調整できる便利なサービスですが、最良の性能を得るためには、
データベースの設定や構造には注意が必要である。

（Chat GPT）
データベースエンジンのバージョンアップデートに際しては、
ユーザーの計画や介入が必要になることもある。
>Cloud SQLを使っていると、時々データベースのソフトウェア
（これを「データベースエンジン」と言います）が
新しいバージョンにアップデートしなければならない事がある。
>
>普段はGoogleがこれらのアップデートを自動的に
>行ってくれるので、ユーザーは特に何もする必要がない。
>
>しかし、時にはこれらのアップデートが、
ユーザーのアプリケーションやデータベースに影響を
与える可能性がある場合、事前にユーザーがアップデートの
計画を立てたり、アップデートの進行に介入しなければならない。
>
>つまり、Cloud SQLは多くの管理作業を
自動化していますが、データベースエンジンの
大きなバージョンアップデートの際には、
ユーザーの注意と準備が必要である。

（Chat GPT）
インスタンスのカスタマイズが可能で、
リソースの使用量に基づいてコストが変動、
これにより、パフォーマンスとコストの
最適なバランスを達成することができる。
>Cloud SQLでは、ユーザーは自分のニーズに
合わせてデータベースのインスタンス
（つまり、個々のデータベースサーバー）を
カスタマイズすることができる。
>
>これにより、必要なリソース（例えば、データを保存するための
メモリやデータベースの処理速度など）を自由に選択できます。

利用するリソースの量に基づいて料金が
変わるため、使った分だけ支払えばOK。
>
>これは、無駄なコストを削減し、必要なパフォーマンスを
得るために、リソースを上手に調整することができるということ。
>
>簡単に言うと、Cloud SQLは自分で設定を
カスタマイズできるので、必要なパフォーマンスを得つつ、
コストを抑える最適なバランスを見つけることができる。

（Chat GPT）
セキュリティ面では、Cloud SQLは休止中および
転送中のデータの暗号化、IAMを用いたアクセス管理、
そして厳格なネットワークセキュリティ設定を提供している。
>Cloud SQLは、データのセキュリティに非常に強く注力している。
まず、保存されているデータ（休止中のデータ）と
インターネットを通じて送られるデータ
（転送中のデータ）の両方を暗号化。
>
>これにより、データが不正に読み取られる
リスクを大幅に低減させることが可能。
>
>さらに、IAM（Identity and Access Management）という
システムを用いてアクセス管理を行うことができる。
>
>これは、誰がデータベースにアクセスできるかを
厳密に制御し、不正アクセスを防ぐためのものである。
>
>また、ネットワークセキュリティ設定も
厳格で、データベースへのアクセスを
安全に保つための様々な設定が可能である。
>
>簡単に言えば、Cloud SQLはデータの暗号化、
アクセス制御、ネットワークの安全性の面で
高度なセキュリティを提供することで、
ユーザーのデータをしっかりと守るサービスである。

（Chat GPT）
地域間レプリケーション、自動フェイルオーバー、
リードレプリカなどの機能により、高い可用性と
効果的な災害復旧オプションを実現している。
>Cloud SQLには、データベースの信頼性と安定性を
高めるためのいくつかの重要な機能がある。
>
>地域間レプリケーション: 
データベースのコピーを異なる地域に作成する機能であり、
一つの地域に何らかの問題が発生した場合に、
別の地域で、コピーを引き続き利用することができる。
>
>自動フェイルオーバー: 
メインのデータベースに問題が発生した場合、
自動的にバックアップのデータベースに切り替わる機能。
これにより、サービスの中断を最小限に抑えることができる。
>
>リードレプリカ: 
メインのデータベースからデータを
読み取るためのコピーを作成する機能。
これにより、データの読み取り負荷を分散させることで、
メインのデータベースへの影響を減らせる。
>
>これらの機能により、Cloud SQLは高い可用性を
実現し、万が一の災害が発生した場合でも
データの復旧が効果的に行えるようになる。
>
>簡単に言えば、Cloud SQLはデータの安全性と
アクセスの安定性を確保するための
強力な機能を備えているデータベースである。

（Chat GPT）
自動バックアップ機能によりデータの復元が容易であり、
定期的なバックアップと災害復旧プランにより、
ビジネスの継続性が保証されている。
>Cloud SQLには自動バックアップ機能が備わっており、
データベースの内容を定期的に自動的に保存する事ができる。
>
>このバックアップ機能のおかげで、もし何か問題が
起きても、過去のデータに簡単に戻すことができる。
>
>さらに、これらの定期的なバックアップは
災害復旧プランの一部として機能する為、
何らかの大きな問題（たとえば自然災害やシステムの障害など）が
発生した場合でも、保存されたバックアップデータを
使ってビジネスを迅速に復旧できるようになっている。
>
>簡単に言えば、Cloud SQLの自動バックアップと
災害復旧機能により、ビジネスデータの安全性が高まり、
万一の事態にもビジネスの継続性が保証されている。

（Chat GPT）
Cloud SQLはGoogle Cloudの他のサービスと
容易に統合でき、オンプレミスシステムや
他クラウドプロバイダーのサービスとの
相互運用性も備えている。
>Cloud SQLは、Google Cloud内の他のサービスと
簡単に統合できる設計になっています。
>
>これは、例えば、データ分析、ストレージ、
コンピューティングリソースなどの
Google CloudのサービスとCloud SQLを
スムーズに連携させることができるという意味である。
>
>これにより、異なるサービス間でデータを効率的にやり取りし、
より複雑なアプリケーションやシステムを構築する事が可能。
>
>さらに、Cloud SQLはオンプレミスシステム
（つまり、企業が自社の施設内に設置したサーバーやデータベース）や
他のクラウドプロバイダーのサービスともうまく連携する事が可能。
>
>これは、異なる環境やプラットフォーム間でデータを
共有したり、一緒に働いたりする際に非常に便利である。
>
>簡単に言えば、Cloud SQLは他のGoogle Cloudサービスや
外部システムとの相互運用性が高く、さまざまな環境での
データ管理とアプリケーションの統合を容易にすることができる。

（Chat GPT）
データ移行プロセスのサポートも提供され、
既存のデータベースシステムからの移行を容易にする。
>Cloud SQLは、データの移行プロセスをサポートしており、
既存のデータベースシステムからCloud SQLへの
データ移行を容易に行うことができる。
>
>たとえば、あなたが他のデータベースサービスや
オンプレミスのデータベースを使用している場合、
Cloud SQLのツールを使って、それらのデータを
Cloud SQLにスムーズかつ効率的に移行することが可能。
>
>この機能により、データの移行に関する複雑さが
減少し、時間と労力を大幅に節約することができる。
>
>つまり、Cloud SQLは既存のデータベースから
新しいシステムへの移行を簡単にし、迅速な移行プロセスを
実現するためのサポートを提供している。
>
>簡単に言えば、Cloud SQLは他のシステムからの
データ移行を簡単かつ効率的に行うことができるサービスです。

（Chat GPT）
ストレージサイズや接続数の上限など、
サービスの制限事項にも注意が必要。
>Cloud SQLを使用する際には、いくつかの制限がある。
主なものには、ストレージサイズの上限と接続数の上限が挙げられる。
>
>ストレージサイズの上限とは、Cloud SQLで使用できる
データの保存量には限界があるということであり、
データベースがある一定の大きさに達すると、
それ以上データを保存することができなくなる。
>
>接続数の上限とは、一度にデータベースにアクセスできる
ユーザーやアプリケーションの数に限りがあるということで、
これが上限に達すると、新たな接続はできなくなる。
>
>これらの制限事項は、Cloud SQLを使用する上での
計画や設計を行う際に重要である。
>
>例えば、大量のデータを扱うアプリケーションを
開発する場合、ストレージの上限を考慮に入れたり、
多くのユーザーが同時にアクセスする可能性がある場合は
接続数の上限を考慮に入れる必要がある。
>
>簡単に言えば、Cloud SQLを使う際には、
ストレージの容量や同時接続数の制限に注意し、
それに合わせて計画を立てなければならない。

</p>
</details> 


## Cloud SQL インスタンス を作成。
`GCPコンソール` から `SQL` を選択。
![gcp_sql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/4de947fc-8cc4-bcfb-3e6b-7cf37a55dfbc.png)

インスタンスを作成。
![sql_create_instance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/9bead4c6-e584-863b-3169-3f573070a470.png)

データベースエンジンの選択。
いずれも最新の `SQLデータベース` を提供していますが、
コミュニティは、新製品用の `PostgreSQL` に同意しているとのこと。
![sql_create_instance_posgre.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/65ae1c71-ae57-43a2-1f42-67c9cfa25252.png)

`インスタンスID` と `パスワード` を入力。
データベースのバージョンは最新を選択してください。

インスタンスID：`poll-database` 
パスワード：`secretpassword`
![sql_create_instance_posgre_info_name_pass.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/a99bd5ce-93d2-dc78-e993-906d575df7c2.png)

Cloud SQL のエディションの選択。
`Enterprice` を選択してください。
![sql_create_instance_posgre_info_edition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/6fc8ddcc-b82f-2fdd-8283-4150a91ea649.png)

[Enterprise Plus](https://cloud.google.com/blog/ja/products/databases/announcing-the-cloud-sql-enterprise-plus-edition-for-mysql-and-postgresql) についてはこちらの記事を参考にしてください。

エディションのプリセットを選択。
今回は検証の為、`サンドボックス` を選択。
![sql_create_instance_posgre_info_edition_priset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/482ce631-68f5-382f-2e55-20e66b1052ce.png)

リージョンとゾーンを選択。

動画では、リージョンは `物理的に遠い場所` を選択と
言われていますが、 `最寄りのリージョン` でも問題ありません。

ゾーンは `シングルゾーン` を選択、
プライマリゾーンは `任意` としてください。
![sql_create_instance_posgre_info_region.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/f7c35ccc-2a5e-8f7d-e5b7-97a47afb48b3.png)

マシンタイプとストレージを選択。
マシンタイプとストレージは、最小のマシン、容量から始めるのがお決まりとの事。
つまりは、1つの仮想CPUと3.75GBのRAMから始めなければならない。
![sql_create_instance_posgre_info_machine.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/418926b7-7813-4a93-6531-91f437fcfe2a.png)

ストレージの種類は、デフォルトのまま、推奨されている `SSD` を選択、
暗号化の方法は、`Googleが管理する暗号鍵` を選択してください。
![sql_create_instance_posgre_info_storage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/0d583478-bce0-4714-e902-69dbdb9255b7.png)

その他の構成オプションはデフォルトのままで、
`インスタンスを作成` をクリック。

なお、インスタンス作成は、時間がかかります。


## Cloud Run Service をデプロイする。
[vote-for-tabs-or-spaces](https://github.com/tomo8332/gcp-sample/tree/main/cloud-run-cloud-sql/python/vote-for-tabs-or-spaces) を、git clone してください。

```
git clone https://github.com/tomo8332/gcp-sample.git
```

git cloneの実行が完了したら、cdコマンドを使って、対象のディレクトリ階層へ移動。

```
cd gcp-sample/cloud-run-cloud-sql/python/vote-for-tabs-or-spaces
```

[README.md](https://github.com/tomo8332/gcp-sample/blob/main/cloud-run-cloud-sql/python/vote-for-tabs-or-spaces/README.md) を読んで、Cloud Run サービスのデプロイを行なってください。

なお、動画の[サンプルコード](https://github.com/GoogleCloudPlatform/serverless-expeditions/tree/main/cloud-run-cloud-sql)は、Dockerイメージを、
`Container Registry` へプッシュします。

`Container Registry` は非推奨となっているため、
このブログでは、`Artifact Registory` に対して、
`Dockerイメージ` がプッシュされるように修正しています。

また、[requirements.txt](https://github.com/GoogleCloudPlatform/serverless-expeditions/blob/main/cloud-run-cloud-sql/requirements.txt) は、Pythonプロジェクトの
依存関係を管理していますが、動画の[サンプルコード](https://github.com/GoogleCloudPlatform/serverless-expeditions/tree/main/cloud-run-cloud-sql)は
パッケージのバージョンの互換性等の問題で、
正常にデプロイすることができない可能性があります。

`Cloud Run Service` のデプロイを行った処、
下記のエラーが表示されました。
```
ImportError: cannot import name 'escape' from 'jinja2'
```
https://stackoverflow.com/questions/71718167/importerror-cannot-import-name-escape-from-jinja2

```
ImportError: cannot import name 'json' from itsdangerous
```
https://stackoverflow.com/questions/71189819/importerror-cannot-import-name-json-from-itsdangerous


## Cloud Shell を使用して、Cloud SQL インスタンスに接続する。
`Cloud SQL` インスタンスが正常にデプロイされた事を確認できたら、
`Cloud SQL` インスタンスを経由して、`Cloud Shell`を起動。
![sql_gcloud_shell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/b4736451-74f3-6e20-5d70-d8ee62658f52.png)

SQLページから `Cloud Shell` を起動すると、ターミナル上に
`Google Cloud SQL` インスタンスに接続するための
コマンドが表示されますので、そのまま実行。
![sql_gcloud_shell_command.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/a1bd499e-4e8e-c9a5-ce33-eb724f50e39f.png)

なお、`Google Cloud SQL` インスタンスに接続するためのコマンドを
実行した際に、`Cloud SQL Admin API` が有効になっていないことを
警告されたら、ターミナル上の指示に従って、APIを有効にしてから、
`gcloud sql connect` コマンドを再実行してください。
![sql_gcloud_shell_command_api.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/7385720a-2cbb-942f-0ef7-d2946170550e.png)
![sql_gcloud_shell_command_api_enable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/e3027fe1-8a6a-83c3-d0ed-121cafb1163d.png)

`gcloud sql connect` コマンドが正常に実行されると、
パスワードの入力を促されるので、ここには、SQLインスタンスを
作成した際に設定したパスワードを入力してください。
![sql_gcloud_shell_command_pass.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/643d50ec-3413-3dd2-f95f-e7671ed44c8a.png)


## テーブル作成 と データ挿入
[README.md](https://github.com/tomo8332/gcp-sample/blob/main/cloud-run-cloud-sql/python/vote-for-tabs-or-spaces/README.md) に記述している、`テーブル作成` と `データ挿入`の
コマンドを、一気にCloud Shellのターミナル上で実行してください。
![sql_gcloud_shell_command_create_table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/3704eb38-e3e4-5515-859c-1f22a3c5b530.png)
なお、`テーブル作成` と `データ挿入` は、`Cloud SQL` インスタンスに
接続された状態でなければ実行することはできません。


## Cloud Run にデプロイされたアプリを動かす。
`Cloud Run Service` が正常にデプロイされて、
下記のアプリケーションが起動すれば成功です。

それぞれのボタンを数回クリックしてみてください。
![sql_cloud_run_tab_space.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/0011ebcc-29f6-c9ba-f40a-8c98822a3f5b.png)


## Cloud SQL にデータが挿入されたかを確認する。
`Cloud SQL` インスタンスに接続した状態で、
下記のコマンドをそれぞれ実行してください。

どのボタンが何回クリックされたのか、
そのボタンが何時、押されたかを
確認することができれば完了です。

```
SELECT * FROM totals;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/b70d8138-be72-ee2a-a8a9-b6d0750b6db4.png)

```
SELECT * FROM votes;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/b5cfb7f8-78f4-39d0-ce7a-1ccffbc8aff8.png)


## 終わりに
今回の記事は、動画を視聴しまして、
実際に『手を動かしてみた』という内容でまとめました。

Cloud SQLは、MySQL、PostgreSQL、SQL Serverなど、
私たちの身直によくあるデータベースエンジンを使用している為、
その仕組みについては、難しく考えることはありませんが、
互換性やバージョン等の問題で途中、
何度か正常にデプロイできないことが続きました。

その問題の対応についても、記述していますので、
`Cloud SQL` データベースについて、
軽く学習してみたいと考えていましたら、
参考にしていただけると幸いです。

また、`Cloud SQL`をデプロイ後、
その`Cloud SQL`をデプロイしたリージョンと
それとは異なるリージョンに、`Cloud Run`を
一つずつデプロイしてみると、
レスポンスに微妙な違いがありますので、
試してみると面白いかもしれません。

あとで『じっくり読みたい』、『繰り返し読みたい』と
思ってくれましたら、『`ストック`』へ登録、
この記事が読まれている方にとって、
参考になる記事となりましたら、『`いいね`』を
付けていただけますと、励みになりますので、
よろしくお願いします。