Cloud Runを開発するGitHubレポを爆速設定するテンプレートを作成した!

# モチベ

- Cloud Run はとても便利でPoCを作るときなどにすぐにデプロイして試す事ができてるが、`gcloud run deploy` で毎回Deployするのは辛くなる
- 開発するにつれて環境変数やResourceなどCloud Runの設定引数が増えてTerraformで管理したくなるが、 ローカルで `terraform apply`するのも結構面倒くさい
- GitHub ActionsからTerraform applyを設定すると便利だが、WorkloadIdentity の設定など毎回コピーしてくるのが面倒くさい

# ゴール

テンプレートにして、毎回基本的な設定ができているrepoを簡単に作れるといい

# Repository Template

最終的なTemplateはこちらです。

https://github.com/nakamasato/cloud-run-app-template

今回テンプレートで作成されるもの

1. Terraform
    1. Cloud Run service (`hello` imageでdeployされる)
    1. GitHub Actions用のService Account及びWorkloadIdentity関連の設定
1. GitHub Actions
    1. TerraformコードのplanとapplyをPR作成とマージでそれぞれ行う

# Usage

## 新規Gitレポをテンプレートから作成

ここでは `cloud-run-app-sample`というレポを設定

```
NEW_REPO=cloud-run-app-sample
```

```
gh repo create $NEW_REPO --public --template=nakamasato/cloud-run-app-template
```

## 設定ファイルを自分のアプリように書く

:::note info
最初のTerraformのbackendやGitHub Actionsで使う部分のリソースの作成は必要なのでローカルにcloneする必要がある
:::

Repoをクローン

```
gh repo clone $NEW_REPO
```

`terraform`ディレクトリに移動

```
cd terraform
```

exampleのtfvarsをコピーする

```
cp terraform.tfvars.example terraform.tfvars
```

`terraform.tfvars`に開発するCloud Runの設定に関する最低限の情報を書く

```
project                = "<gcp project>"
region                 = "<gcp region e.g. asia-northeast1>"
service_name           = "<cloud run service名 e.g. cloud-run-app-sample"
github_owner           = "<github owner e.g. nakamasato>"
github_repository      = "<github repository e.g. cloud-run-app-sample>"
github_actions_sa_name = "<GitHub Actions用のService Account名 e.g. ga-cloud-run-app-sample"
gh_oidc_pool_id        = "<GitHub Actions OIDC Pool ID e.g. ga-cloud-run-app-sample>"
gh_oidc_provider_id    = "<GitHub Actions OIDC Provider ID e.g. ga-cloud-run-app-sample"
```

:::note info
Cloud Runの詳細設定を書きたい場合には、`cloud_run.tf`の中身に書く。内部的には、https://github.com/GoogleCloudPlatform/terraform-google-cloud-run というModuleを使っているのでこのモジュールのInputを参照。
:::

Terraformのbackendの設定を `terraform.tfbackend`に記載

```
cp terraform.tfbackend.example terraform.tfbackend
```

```
bucket  = "<gcs bucket>"
prefix  = "<prefix>"
```

:::note info
一つのバケットをTerraformのbackendとして共通で使う場合は、`prefix`にrepository名に対応させるとわかりやすい

`test-app-a` repoで `test-app-a`を管理する場合:

```
bucket  = "cloud-run-template-naka-terraform"
prefix  = "test-app-a"
```
`test-app-b` repoで `test-app-b`を管理する場合:

```
bucket  = "cloud-run-template-naka-terraform"
prefix  = "test-app-b"
```
:::

## GCP リソースを作成

上記の設定を元にこのステップでGCPのリソースを作成

gcloud login

```
gcloud auth application-default login
```

terraform init

```
terraform init -backend-config=terraform.tfbackend
```

terraform apply

```
terraform apply
```

:::note warn
この段階で、必要なAPIが有効化されるタイミングで、applyに失敗する可能性がある。失敗した場合は、再試行すると成功する。
:::

## GitHub レポのシークレットを設定

:::note info
GitHub Actionsが使う workload identity provider `PROVIDER_NAME`とservice accountのemail `SA_EMAIL`をGitHubのRepository Secretに設定
:::


`gh`をつかうので `gh auth login` しておく必要がある


```
gh secret set PROVIDER_NAME --body=$(terraform output github_actions_provider_name | tr -d '"')
gh secret set SA_EMAIL --body=$(terraform output github_actions_sa_email | tr -d '"')
```

## PR作成!

すべての準備が整ったので、ローカルの変更をコミットして PRを作成してみる！

:::note info
PRでterraform planのGitHub Actionsが実行される :tada: 
:::


![Screenshot 2024-05-05 at 11.06.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/e96b73bc-9ad9-ebc8-6c66-aac363a05e5f.png)

一つ前のステップですでにローカルから`terraform apply` してあるので、この時点では `No changes`となる。

以後、Cloud Runの設定を変更すれば、PR上でReviewして、MergeしたらApplyできる設定となる。

# Application

レポの設定ができたらアプリケーションの開発へ

1. [GCP Cloud Run (Python) 備忘録](https://qiita.com/nakamasato/items/6ddc934b1a1f90d41fae)
1. [GCP Cloud RunのSLO monitoringをterraformで作成](https://qiita.com/nakamasato/items/22b7fa3b5e1c3d06e9d4)

# TODO

まだまだテンプレートにかけている機能はたくさんあるので、絶賛更新中！

- [ ] GitHub Actionsでappの最新版のイメージのBuildとCloud RunへのDeploy
- [ ] Dev環境とProd環境を別のCloud Run serviceとして作成できるOptionを作る
- [ ] PR用の環境をつくれるようにする
- [ ] Cloud Run モニタリングもTemplateで設定 ([GCP Cloud RunのSLO monitoringをterraformで作成](https://qiita.com/nakamasato/items/22b7fa3b5e1c3d06e9d4))