GAE/Go + Cloud Build でデプロイを自動化しよう

こんにちは、今年も花粉症の季節でアレルギー症状に苦しんでる @wezardnet です🤧
最近は洗濯して再利用できるマスクが発売されてるとのことで試しに購入してみました。使用感はなかなか良いと思います。一度洗ってみましたが、あと２、３回洗っても使えそうな感じです！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">花粉症の季節に洗濯できて繰り返し使えるというマスクを購入。<br>カラバリも豊富で使い捨てよりお財布に優しいのがうれしい😊｜wezardnet <a href="https://twitter.com/wezardnet?ref_src=twsrc%5Etfw">@wezardnet</a>｜note（ノート） <a href="https://t.co/2DCUSjlFbr">https://t.co/2DCUSjlFbr</a></p>&mdash; wezardnet (@wezardnet) <a href="https://twitter.com/wezardnet/status/1108331254087217152?ref_src=twsrc%5Etfw">2019年3月20日</a></blockquote>


# 1. TL;DR
Google Cloud Build は Google Cloud Next ’18 で発表された Google の CI/CD サービスです。
詳しいサービス概要については [公式ドキュメント](https://cloud.google.com/cloud-build/docs/overview?hl=ja) にお任せするとして、ここでは割愛させていただきます ☆(・ω<)

連携可能なリポジトリは、、、

* GitHub
* Bitbucket
* Cloud Source Repositories

となっています。また、

* Kubernetes Engine
* App Engine
* Cloud Functions
* Firebase

にデプロイ可能なようですが、今回は GitHub(private repositories) & App Engine(Standard Environment) で試してみました。


# 2. 構成
全体の構成は GitHub リポジトリを Cloud Source Repositories にミラーリングして次のようになります。ミラーリングの方法については公式ドキュメントの [GitHub リポジトリのミラーリング](https://cloud.google.com/source-repositories/docs/mirroring-a-github-repository?hl=ja) を参照ください。

![Cloud Build 構成図.png](https://qiita-image-store.s3.amazonaws.com/0/12023/7859ffd0-87bb-8377-ac2f-31b4c1c9e469.png)

これで GitHub master ブランチが更新されたら Cloud Build に通知され App Engine にデプロイされるようになります。


# 3. cloudbuild.yaml を用意する
次にビルド構成ファイルを書きます。
私のプロジェクトは default サービスと backend サービスに分かれているので、それぞれでデプロイを実行する格好になってます。

```yaml:cloudbuild.yaml
steps:
- name: gcr.io/cloud-builders/gcloud
  args: ['app', 'deploy', '--version', 'dev', 'app.yaml', 'cron.yaml']
- name: gcr.io/cloud-builders/gcloud
  args: ['app', 'deploy', '--version', 'dev', 'backend.yaml']
  waitFor: ['-']

- name: gcr.io/cloud-builders/gsutil
  args: ['rm', '-r', 'gs://asia.artifacts.{Project ID}.appspot.com/*']
- name: gcr.io/cloud-builders/gsutil
  args: ['rb', 'gs://asia.artifacts.{Project ID}.appspot.com']
```

デプロイ後に gsutil でゴニョゴニョやっているのは Google Cloud Storage(GCS) に `asia.artifacts.{Project ID}.appspot.com` というバケットが自動的に作られ、その中にコンテナ イメージが格納されストレージコストが課金されてしまうので、ごっそり削除する処理を入れてます😝

**- 追記 2019.03.28 -**
gsutil まわりの処理は [オブジェクトライフサイクル管理](https://cloud.google.com/storage/docs/lifecycle) で実装しても良さそうです。。。

![gcs01.png](https://qiita-image-store.s3.amazonaws.com/0/12023/f66f033a-f6f1-d2a3-533b-ec86f907e33b.png)

`asia.artifacts.{Project ID}.appspot.com` の中にはデプロイするたびに sha256 で始まるファイルが作られ格納されていきます。サイズもちょい大きいので、放置しておくとストレージコストが地味に効いてきます（笑）

![gcs02.png](https://qiita-image-store.s3.amazonaws.com/0/12023/85f489fb-f656-3ae5-463c-1bf0f643764e.png)

というわけで、極力課金を抑えたい私はデプロイした後にバケットを削除するコマンドを入れました。ちなみに gsutil でバケットを削除するには、中身のオブジェクトをすべて削除しないとエラーになります💡

尚、デプロイ時に自動的に作られる `asia.artifacts.{Project ID}.appspot.com` というバケットがなんなのか調べた方がいらっしゃいますので、その正体を知りたい人は [Google App EngineのNode.js/Standard環境の仕組みについて調べてみた](https://qiita.com/junjis0203/items/c3779e7e488ae547fb5a) を読んでいただくと良いかと思います。


# 4. Cloud Build トリガーを設定する
[Google Developer Console](https://console.cloud.google.com/) のメニューから Cloud Build を選択します。
左ペインのメニューから「Triggers」を選択し、「Create trigger」、もしくは「Add trigger」ボタンを押します。

![image01.png](https://qiita-image-store.s3.amazonaws.com/0/12023/5e2b1345-0c40-da16-0cf9-fd1c377635d2.png)

ソース選択の画面で「Cloud Source Repository」を選び、次にリポジトリの選択を行います。前述のミラーリングしたリポジトリが出てくるのでコイツを選ぶと、トリガーの詳細を設定する画面になります。

![image01.png](https://qiita-image-store.s3.amazonaws.com/0/12023/abb327c9-0764-a9d2-d155-2b7bd9d121bf.png)

表示される説明のとおりに項目を入力していけば OK です。特筆すべき点としては、ビルド設定で **Cloud Build 構成ファイル** を選択し cloudbuild.yaml の場所を指定するぐらいでしょうか...

設定が完了すると、一覧に表示されます。

![image01.png](https://qiita-image-store.s3.amazonaws.com/0/12023/9b1e22bf-6ee2-f3e2-472e-69b8758c79fd.png)

尚、本画面の「Run trigger」をクリックすると、手動で実行させることもできます。

![image02.png](https://qiita-image-store.s3.amazonaws.com/0/12023/239b557f-ac81-2fb5-3a07-685a4cffe3c8.png)


# 5. ビルド履歴
左ペインのメニューから「History」を選択すると、これまでの実行履歴を確認することができます。

GitHub リポジトリの master ブランチに更新が入るとトリガーが起動し、ステータスアイコンがローディングします。正常に終了すると✅となります。エラーで終了した場合は❗️で表示されるので、詳細を開いてどのステップで躓いているのか確認しましょう。

![image02.png](https://qiita-image-store.s3.amazonaws.com/0/12023/6f1549db-334b-e85c-cbb8-e6ed7de26256.png)

実際に App Engine にデプロイ出来ているのか、アクテビティ ログで確認してみます。

![image01.png](https://qiita-image-store.s3.amazonaws.com/0/12023/9220a3c6-da0e-ac76-8054-eb740ac075c2.png)

おぉ cloudbuild.yaml で書いたとおりにステップが実行されていることがわかります。デプロイが終わるまでに大体２〜３分弱ってところでしょうか、、、

これでソース リポジトリとデプロイの連携ができて、運用管理が楽になりましたね😄