Rust のアプリケーションを Google Cloud Run で動かして Google Cloud Build を使って自動デプロイする

# はじめに

* Google Cloud Run はマネージドサーバー上で Docker コンテナを起動できるサービスです。
* この記事では Cloud Run で Rust のアプリケーションを動かして Cloud Build を使って自動デプロイする手順をまとめてみます。

# Cloud Run について

* Cloud Run に Docker コンテナを登録するとリクエスト到達時にコンテナが起動しサービスを提供します。
* 利用料金は CPU 利用時間、メモリ利用量、リクエスト数などでの従量課金です。ベータ期間だけ無料利用枠があるようです。
* App Engine でもマネージドサーバー上でコンテナを起動することができるので比較すると、App Engine がコンテナの常時起動であるのに対して Cloud Run はリクエスト時のみの起動になるため利用料金を抑えられるメリットがあります。
* Cloud Functions もマネージドサーバー上でサービスを提供することができるので比較すると、Cloud Functions が特定の実行環境のみで提供されるのに対して Cloud Run は任意のコンテナを利用することができるので自由度が高いというメリットがあります。


# GCP コンソールから Cloud Run を有効にする

* GCP コンソールにアクセスし Cloud Run のページを開いて有効にします。


# gcloud コマンドを最新にする

* gcloud コマンドで Cloud Run へのデプロイができるように最新にします

```sh
gcloud components install beta
gcloud components update
```


# サンプルをダウンロードする

* hello world のサンプルがあるのでダウンロードします。

https://github.com/knative/docs/tree/master/community/samples/serving/helloworld-rust

* 階層が深いので helloworld-rust をルートとしたリポジトリを作成して github にアップロードします
* サンプル自体は hyper を利用した単純なウェブサービスです。

# Docker イメージをビルドする

* Dockerfile が用意されているので gcloud コマンドでビルドします

```
gcloud builds submit --tag gcr.io/PROJECT-ID/helloworld
```

# Cloud Run にデプロイする

* gcloud コマンドで Cloud Run にデプロイします
* Cloud Run は現在 us-central1 リージョンでしか提供されていないので、デフォルトリージョンが異なる場合は --region オプションで指定する必要がある

```
gcloud beta run deploy --image gcr.io/PROJECT-ID/helloworld --platform managed --region us-central1
```

* デプロイが成功するとサービスの URL が表示されるのでアクセスして動作を確認する



# Cloud Build の設定ファイルを用意する

* Cloud Build 用の設定ファイルを用意します
* 内容は Docker イメージをビルドして Cloud Registry に push して Cloud Run にデプロイするというものです

```yaml:cloudbuild.yaml
steps:
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '-t'
      - 'gcr.io/$PROJECT_ID/helloworld:${SHORT_SHA}'
      - '.'
  - name: 'gcr.io/cloud-builders/docker'
    args: ["push", "gcr.io/$PROJECT_ID/helloworld"]
  - name: 'gcr.io/cloud-builders/gcloud'
    args:
      - 'beta'
      - 'run'
      - 'deploy'
      - 'helloworld'
      - '--image'
      - 'gcr.io/$PROJECT_ID/helloworld:${SHORT_SHA}'
      - '--region'
      - 'us-central1'
```


# Cloud Build のトリガーを用意する

* GCP コンソールから Cloud Build のトリガーを用意します
* サンプルのリポジトリを指定して下記の内容でトリガーを作成します

```
名前: Cloud Run デプロイ
トリガーのタイプ: ブランチ
ブランチ: .*
ビルド設定: Cloud Build 構成ファイル
Cloud Build 構成ファイルの場所: cloudbuild.yaml
```

# Cloud Build から Cloud Run へデプロイする権限を追加する

* 下記の手順の通り Cloud Build のビルド実行ユーザーへ Cloud Run を利用する権限を追加します

```
1. Google Cloud Console で [IAM] ページを開く

2. プロジェクトを選択し、[続行] をクリック

3. メンバーリストで、[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com という名前の Cloud Build サービス アカウントを探す。ここでの [PROJECT_NUMBER] は GCP プロジェクトのプロジェクト番号

4. その行の鉛筆アイコンをクリック

5. [別の役割を追加] をクリック

6. [役割の選択] プルダウン メニューから [Service Accounts] を選択し、[サービスアカウント ユーザー] を選択

7. [別の役割を追加] をクリック

8. [役割の選択] プルダウン メニューから [Cloud Run] を選択し、[Cloud Run 管理者] を選択

9. [保存] をクリック

10. [別の役割を追加] をクリック

11. [役割の選択] プルダウン メニューから [Project] を選択し、[編集者] を選択

12. [保存] をクリック
```

* 作成したトリガーを実行して動作を確認します。

# おわりに

* GCP で Rust の実行環境を用意しようとすると GAE でも GCE でも GKE でもサーバーを常時起動する必要があったので手軽に用意できなかったのですが Cloud Run のおかげで安価な環境を用意できるようになったのがうれしいです。

# 参考URL

* 今回つくったサンプルプロジェクト
  * https://github.com/nirasan/helloworld-rust-cloud-run-and-cloud-build
* Cloud Build で Cloud Run へデプロイする手順がまとまっていた記事
  * https://medium.com/google-cloud/simplifying-continuous-deployment-to-cloud-run-with-cloud-build-including-custom-domain-setup-ssl-22d23bed5cd6
* Cloud Build で App Engine へデプロイする手順を以前自分でまとめた記事
  * https://qiita.com/nirasan/items/12caed5d6fbb56ac15e4