LoginSignup
11
5

More than 3 years have passed since last update.

GitlabとGCPのCloudBuildを連携して、ビルド・デプロイを自動化する

Last updated at Posted at 2020-12-17

はじめに

今担当しているウェブシステムをGithubから社内のGitlabに移行しています。この移行に伴い、ビルドやデプロイを自動化するためCI/CDを導入しようと思っています。
導入するには、GitlabのCIやGCPのCloud buildを利用しようと思っているので、この間今週からGitlabのCIやGCPのCloud buildCloud Runなどを触ってみました。

事前準備

  • GCPのプロジェクトを作成する
  • Gitlabリポジトリを作成して、サンプルコードやDockerfileを用意する

今回はgo言語で非常に簡単なウエブアプリを作りました。

ディレクトリ構成は以下のようです。

my_sample_project
│  Dockerfile
│  go.mod
|  cloudbuild.yml
|  main.go
main.go
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

const serverPort = 8080

func handler(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(map[string]string{"message": "Welcome to Linkbal Advent Calendar 2020"})
}

func main() {
    fmt.Printf("Starting server on port %d.....\n", serverPort)

    http.HandleFunc("/", handler)

    log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", serverPort), nil))
}
Dockerfile
FROM golang:1.14.13-buster as builder

WORKDIR /app

COPY go.* ./
RUN go mod download

COPY . .

# Build the binary
RUN go build -mod=readonly -v -o server

FROM debian:buster-slim
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/server /app/server

CMD ["/app/server"]
  • cloudbuild.yml: Cloud Buildの構成ファイルです。後で説明します。

自動ビルド

まず、Gitlabから自動的にCloud Buildでコンテナーイメージをビルドできるようにします。

これを実現するには、以下の2つ方法あります。

1. GitlabのCIを使用しない方法

  • まず、GitlabのリポジトリをGCPのCloud Source Repositoriesにミラーリング(Mirroring)する

このGCPの公式ガイドに沿って簡単にミラーリングを設定できます。

  • Cloud Buildのトリガーを使って、ソースコードを変更するたびに、自動のビルドを設定する

GCP管理画面でCloud Buildの新規トリガーを作成する

スクリーンショット 2020-12-17 23.34.58.png

  • イベント: トリガーを発火するリポジトリの3つイベントという選択肢がありますが、最後は「Githubアプリのみ」ですので、最初2つ選択肢しか選択できません。
    • ブランチにpushする: 特定のブランチに対してcommitが行われたときにビルドを開始するトリガーを設定します。
    • 新しいタグをpushする: 特定のタグを含むCommitが行われたときにビルドを開始するトリガーを設定します。

本番環境へのデプロイの時のみ使う場合、ブランチにpushするを選択して、masterブランチにプッシュするたびにビルドを開始するという設定でいいですが、テスト環境へのデプロイでも使いたい場合、新しいタグをpushするの方がいいですね。開発中にコードをPushするたびに、ビルド・デプロイが必要ないだから。

  • リポジトリ: 上のステップにGitlabからミラーリング済みのリポジトリです。
  • タグ: .*:全てのタグ
  • ビルドの構成: リポジトリ内にCloud Build 構成ファイルを指定する

Cloud Buildの構成ファイル

cloudbuild.yml
steps:
  # コンテナーイメージをビルド
  - name: "gcr.io/cloud-builders/docker"
    args: [ "build", "-t", "asia.gcr.io/$PROJECT_ID/trantan_ci_example:${TAG_NAME}", "." ]
  # コンテナーイメージをプッシュ
  - name: 'gcr.io/cloud-builders/docker'
    args: [ 'push', 'asia.gcr.io/$PROJECT_ID/trantan_ci_example:${TAG_NAME}']

images:
  - "asia.gcr.io/$PROJECT_ID/trantan_ci_example:${TAG_NAME}"

logsBucket: 'gs://trantan_ci_example_cloudbuild_logs'

上のトリガーの設定でブランチにpushするを選択した場合、${TAG_NAME}(タグ名)の代わりに、${COMMIT_SHA}を使ってください。

この方法で、自動のビルドだけではなく、CloudFunctionsの自動デプロイでも実現できそうですね。

2. GitlabのCIを使用する方法

GCP側で設定する

まず、GCP管理画面で以下の必要な設定をします。

  • Cloud Build APIを有効にする
  • Cloud Build用サービスアカウントを作成する
    スクリーンショット 2020-12-17 11.08.55.png

    • 「Cloud Build サービス エージェント」権限ロールを付与する
    • 作成したサービスアカウントに対するJSONキーを作成する

GitlabのレポジトリのCI/CDを設定する

  • リポジトリにCIのRunnerを追加する: Settings > CI/CD > Runners

スクリーンショット 2020-12-17 12.43.28.png

  • GCPの情報を保存するためのレポジトリの変数を作成する: Settings > CI/CD > Variables

スクリーンショット 2020-12-17 12.59.24.png

GCP_PROJECT_ID: GCPのプロジェクトID
GCP_SERVICE_KEY: 上のステップで作成したサービスアカウントのJSONキー

GitlabのリポジトリにCIを追加する

プロジェクトディレクトリーに.gitlab-ci.ymlを追加する

.gitlab-ci.yml
stages:
  - test
  - build

# コードフォーマット、テスト
test:
  stage: test
  # Lintチェックやユニットテスト実行など追加する

# ビルド
cloud_build:
  stage: build
  image: google/cloud-sdk
  before_script:
    - echo $GCP_SERVICE_KEY > gcloud-service-key.json # Google Cloud service accounts
  script:
    - gcloud auth activate-service-account --key-file gcloud-service-key.json
    - gcloud config set project $GCP_PROJECT_ID
    - gcloud builds submit . --config=cloudbuild.yml --substitutions=TAG_NAME="$CI_COMMIT_TAG"
  # タグ付きコミットをプッシュした際に、行われる
  # コミットをプッシュするたびに、行われる場合、このオプジョンが要らない
  only:
    - tags

これでタグを付けて、コミットをプッシュした際に、自動的にビルドできます。

CIのJobのログは以下の通りです。

スクリーンショット 2020-12-17 14.37.42.png

自動デプロイ

最後、Cloud Buildでビルドしたコンテナーイメージを使用して、Cloud Runサービスを自動的にデプロイする方法を説明したいと思います。

GCPの設定を変更する

GCP管理画面で、Cloud Build > 設定ページを開いて、サービスアカウント権限でCloud Runにデプロイできるように、Cloud Run権限を有効にする

スクリーンショット 2020-12-17 22.51.31.png

Cloud Buildの構成ファイルを変更する

Cloud Buildでビルドした後に、Cloud Runにビルドしたコンテナーイメージを使ってデプロイするように、以下のステップをcloudbuild.ymlファイルのstepsに追加する

cloudbuild.yml
steps:
  # cloud runにデプロイ
  - name: "gcr.io/cloud-builders/gcloud"
    args: ['run', 'deploy', 'trantan-ci-example-app', '--image', 'asia.gcr.io/$PROJECT_ID/trantan_ci_example:${TAG_NAME}', '--region', 'asia-northeast1', '--platform', 'managed', '--allow-unauthenticated']

trantan-ci-example-app: サービス名

結果は以下の通りです。

スクリーンショット 2020-12-17 23.15.21.png

このサンプルのアプリはCloud Runにデプロイしましたが、ビルドしたコンテナーイメージを使って、他のサービスにもデプロイできます。例えば、僕が担当しているサービスは今GKE(Google Kubernetes Engine)上で動いてるので、CIのdeployステージやジョブを追加して、gcloudコマンドでデプロイできそうです。

おわりに

今回は検証のため、GitlabやGCPのドキュメントに参考しながらCloud BuildCloud Runを触って、非常に簡単なサンプルのアプリだけど、自動的にビルド・デプロイを実現できました。

これから実際のサービスに導入してみようと思いますので、都合が良いときに、これに関する記事をまた書こうと思います。

参考

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5