Cloud Buildを用いてCloud Runへのデプロイを自動化する


Google Cloud上のCloud Runへのデプロイを自動化する手法を紹介します。   
今回はSpring Initializrを用いて作成したJavaアプリケーションをデプロイしていきます。  
またGoogle Cloud内で完結させたかったため、ソースレポジトリにはGitHubではなくCloud Source Repositoriesを使用しています。

## 目次 <!-- omit in toc -->
- [使用サービス](#使用サービス)
- [Cloud Runへのデプロイの流れ](#cloud-runへのデプロイの流れ)
- [手順](#手順)
  - [Cloud Source Repositoriesの設定](#cloud-source-repositoriesの設定)
  - [Artificial Repositoryの設定](#artificial-repositoryの設定)
  - [Cloud Run・Cloud Buildの設定](#cloud-runcloud-buildの設定)
  - [Dockerfileとcloudbuild.yamlの設定](#dockerfileとcloudbuildyamlの設定)
- [参考文献](#参考文献)

## 使用サービス
- Cloud Source Repositories
- Artifact Repository 
- Cloud Run
- Cloud Build

## Cloud Runへのデプロイの流れ
デプロイの流れは以下のようになっています。

1.  開発者がCloud Source RepositoriesへソースコードをPush
2.  Cloud BuildがPushをトリガーとして起動
3.  レポジトリ上のDockerfileを基にコンテナイメージがビルドされ、Artifact Registryに作成されたイメージがPushされる
4.  Artifact Registryに格納されているイメージをCloud Runへデプロイ

![デプロイの流れ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685687/da4ab267-04bb-78b9-7a53-5cbf7d95c68c.png)

## 手順
### Cloud Source Repositoriesの設定
1. 初めに[こちらの記事](https://zenn.dev/tatsuyasusukida/scraps/48f993dfc438d9)を参考に、Spring Bootで簡易的なサーバを作成します。
2. Google CloudのコンソールからCloud Source Repositoriesのページに移動します。
3. [リポジトリを追加]->[新しいリポジトリを作成]へ選択し、リポジトリ名・プロジェクト名を入力後[作成]を押します。
4. 作成後、いくつかの手法でコードをPushする手順が表示されるので、個人に合った方法でコードをPushしてください。

### Artificial Repositoryの設定
1. Google CloudのコンソールからArtifact Repositoriesのページに移動し、[リポジトリを作成]を押してください。
2. リポジトリ名を入力後、形式を[Docker]、ロケージョンタイプを[リージョン]、デプロイするリージョンを[global]にします。
3. 他の設定はデフォルト設定のまま[作成]を押します。

### Cloud Run・Cloud Buildの設定
1. Google CloudのコンソールからCloud Runのページに移動し、サービスを作成してください。
2. [ソースリポジトリから新しいリビジョンを継続的にデプロイする]->[Cloud Buildを設定]を選択してください。
3. リポジトリプロパイダーに[Cloud Source Repositories]、リポジトリに自身で入力したリポジトリ名を選択し[次へ]を押下してください。
4. Pushトリガーにしたいブランチを入力、ビルドタイプを[Dockerfile]に選択後[保存]を押します。
5. 続いてサービス名とリージョンを入力し、認証を[未認証の呼び出しを許可]に選択後、他の設定はデフォルトのまま[作成]を押すと、Cloud Runのサービスが作成されます。
6. 作成したCloud Runのサービス詳細画面に遷移するため、[継続的デプロイを編集します]へと移動してください。
7. 今回はCloud Build構成ファイルを自身で作成するため、[構成]->[ロケーション]->[リポジトリ]を選択してください。
8. 次に、特段の理由が無い限り[サービスアカウントのメールアドレス]に入力されているアドレスを空にしたほうがトラブルが起きずに良いです。
9. これらが設定できたら[保存]を押し、Cloud Buildの設定を完了させます。
  
### Dockerfileとcloudbuild.yamlの設定
1. Cloud Buildがbuild時に使用するDockerfileに以下の内容で格納し、コードを保管しているレポジトリのルートディレクトリに配置してください。
```
#
# Build stage
#
FROM eclipse-temurin:17-jdk-jammy AS build
ENV HOME=/usr/app
RUN mkdir -p $HOME
WORKDIR $HOME
ADD . $HOME
RUN chmod +x ./mvnw
RUN ./mvnw -f $HOME/pom.xml clean package

#
# Package stage
#
FROM eclipse-temurin:17-jre-jammy
ARG JAR_FILE=/usr/app/target/*.jar
COPY --from=build $JAR_FILE /app/runner.jar
EXPOSE 8080
ENTRYPOINT java -jar /app/runner.jar
```

2. Cloud Buildが何を行うかを指定するcloudbuild.yamlを以下のように作成し、コードを保管しているレポジトリのルートディレクトリに配置してください。
```
steps:
  # build the container image 
  - name: gcr.io/cloud-builders/docker
    args: [ 'build', '-t', '[artifact registryのリージョン]-docker.pkg.dev/[自身のプロジェクト名]/[artifact registryのレポジトリ名]/[イメージ名]:latest', '.' ]
    # args: ['build', '-t', '$_AR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA']

  # Push the container image to Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', '[artifact registryのregion]-docker.pkg.dev/[project名]/[artifact registryのrepositry名]/[イメージ名]:latest']
    # args: ['push', '$_AR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA']

  # Deploy container image to Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args:
      - 'run'
      - 'deploy'
      - '[Cloud Runのサービス名]'
      - '--image'
      - '[artifact registryのregion]-docker.pkg.dev/[project名]/[artifact registryのrepositry名]/[イメージ名]:latest'
      - '--region'
      - '[Cloud Runのregion]'
```

3. 以下のディレクトリ構成になっていれば、Cloud Source RepositoriesにPushするとアプリケーションがCloud Runへ自動的にデプロイされます。

![ディレクトリ構成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685687/32429f40-f479-a60b-16be-235641474964.png)


## 参考文献
- [JavaでSpring Bootを使ってWebサーバーを作る](https://zenn.dev/tatsuyasusukida/scraps/48f993dfc438d9)
- [Spring Initializr](https://start.spring.io/)
- [コンテナイメージをビルドします](https://cloud.google.com/build/docs/building/build-containers?hl=ja)
- [Clour Buildを使用したCloud Runへのデプロイ](https://cloud.google.com/build/docs/deploying-builds/deploy-cloud-run?hl=ja#continuous_deployment)
- [サービスアカウントを指定した際に起きるエラー解決](https://www.googlecloudcommunity.com/gc/Developer-Tools/Build-is-not-triggered-by-Cloud-build/m-p/554960)
- [Artificial Repositryのリージョン起因のエラー解決](https://zenn.dev/arkbig/scraps/d1dd32e0d4af24)