Google Cloud BuildでCI/CD

# Agenda

1. Google Cloud Buildとは？
2. CI/CDでのCloudBuild活用例

---

# 1. Google Cloud Buildとは？

---

# 1-1. 概要

```text
Google Cloud Platform のインフラストラクチャでビルドを行うサービスです。
さまざまなリポジトリやクラウドストレージスペースからソースコードをインポートし、
仕様に合わせてビルドを実行し、DockerコンテナやJavaアーカイブなどのアーティファクトを生成できます。
(Google Cloud Build公式ドキュメントから抜粋)
```

---

図にするとこんな感じ
<img width="70%" alt="スクリーンショット 2019-11-01 10.40.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252063/cf25dd8d-f025-3be8-0c98-2eb1b44919ed.png">


---

# 1-2. 特徴

* ネイティブDockerをサポート
* カスタムワークフローが定義可能
* 高速なビルド
* ビルドツールを自由に選択できる
    * Maven、Gradle、Webpack、Go、Bazelなど

---

# 1-3. ビルド実行パターン

1. 手動実行
2. ビルドトリガーを使用した自動実行
3. Githubアプリトリガーからの実行

---

# 1-4. 手動実行のコマンド紹介

##### Dockerfileを直接ビルドする場合

```shell
~$ ls
Dockerfile
~$ gcloud builds submit --tag {ホスト名}/{PROJECT_ID}/{任意の名前} .
```
* ホスト名
    * `Container Registry`のホスト名である`gcr.io` か `.gcr.io` のネームスペースで指定可能

##### ビルド構成ファイルをビルドする場合

```shell
~$ gcloud builds submit --config={Yamlの構成ファイル名} {ソースコードディレクトリの相対パス}
```

---

# 1-5. ビルド構成ファイル

* サンプルビルド構成ファイル

```yaml
steps:
- name: 'gcr.io/cloud-builders/git'
  args: ['clone', 'https://github.com/GoogleCloudPlatform/cloud-builders']
  env: ['PROJECT_ROOT=hello']
- name: 'gcr.io/cloud-builders/docker'
  args:
  - 'build'
  - '-t'
  - 'gcr.io/my-project-id/myimage'
  - '.'
images: ['gcr.io/my-project-id/myimage']
```

---

# 1-5-1. フィールド説明

* steps
    * ここにビルドステップを定義していく
* name
    * ビルダーを指定(git, docker, gcloudなど)
    * [標準で提供されているビルダー](https://github.com/GoogleCloudPlatform/cloud-builders)
    * [コミュニティー提供のビルダー](https://github.com/GoogleCloudPlatform/cloud-builders-community)
* env
    * ステップ実行時に使用される環境変数のリストを指定
* args
    * nameフィールドで指定したビルダーに渡す引数を指定
* images
    * レジストリにpushしたいimage名を配列で指定

*※フィールドは他にもたくさんあるので詳細は[ドキュメント](https://cloud.google.com/cloud-build/docs/build-config?hl=ja)を確認してください*

---

# 2. CI/CDでのCloudBuild活用例

---
# 2-1. ビルド/デプロイ自動化前
<img width="80%" alt="スクリーンショット 2019-11-01 11.43.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252063/6cee87a2-7d19-e88f-875a-29e052e6449f.png">

---

# 2-2. ビルド/デプロイ自動化後 (静的ファイルを除く)
<img width="80%" alt="スクリーンショット 2019-11-01 11.39.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252063/4a03d614-d83d-689c-973e-637409bcef14.png">

---

# 2-3. CIテストの自動化について

* Cloud Build公式の[Github連携ツール](https://cloud.google.com/cloud-build/docs/run-builds-on-github?hl=ja)を使用
* 特徴
    * commitをpushするたびに自動でビルド実行
* CIテストで採用した理由
    * commit単位でテストをしたい
    * プルリクページでビルドステータスを確認できる
* 設定手順
  1. GithubとCloud Buildを連携  (詳細手順は[公式ドキュメント](https://cloud.google.com/cloud-build/docs/run-builds-on-github?hl=ja#installing_the_google_cloud_build_app)を参照してください)
  2. ソースコードのルートディレクトリに `cloudbuild.yaml` という名のビルド構成ファイル作成

---

# 2-3-1. CIテスト専用のビルド構成ファイル

```yaml
# cloudbuild.yaml

steps:
# mysql, redisサーバを起動
- name: 'gcr.io/$PROJECT_ID/docker-compose'
  args: ['-f', 'docker-compose.test.yml', 'up', '-d', 'mysql-test', 'redis-test']
# アプリケーションサーバを起動
- name: 'gcr.io/$PROJECT_ID/docker-compose'
  args: ['-f', 'docker-compose.test.yml', 'up', '-d', 'application-server']
# テストシェル実行
- name: 'gcr.io/cloud-builders/docker'
  env: ['MIX_ENV=ci_test']
  args: ['exec', 'application-server', 'sh', '_run-ci-test.sh']
timeout: 900s
```

---

# 2-4. ソースコードの自動ビルドについて

---

* Cloud Build公式の[ビルドトリガーを使用](https://cloud.google.com/cloud-build/docs/running-builds/automate-builds?hl=ja)を使用
* 特徴
    * ソースコードに変更がpushされるたびにビルド実行(トリガーで`ブランチ`を指定した場合)
    * Githubアプリトリガーよりも柔軟な設定可能
    * トリガー
        * gitリポジトリの`ブランチ`or`タグ`の指定が可能
* 設定手順
  1. Cloud Buildのサービスページのサイドバーからトリガーを作成 (詳細手順は[公式ドキュメント](https://cloud.google.com/cloud-build/docs/running-builds/automate-builds?hl=ja)を参照してください)

---

# 2-4-1. ソースコードビルド構成ファイル
この構成ファイルでは、ビルド&デプロイコマンドが定義されているシェルスクリプトを実行するようにしています。

```yaml
# _cloudbuild-dev-all.yaml

steps:
# # ソースコードのビルド
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    bash _build.sh

# ソースコードのデプロイ
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    bash _deploy.sh

timeout: 1200s

```
* entrypoint
    * ビルダーのデフォルトのエントリポイントを使用しない場合に指定する

---

完

---

## 参考文献

[Cloud Build公式ドキュメント](https://cloud.google.com/cloud-build/docs/?hl=ja)