📝

【あなたもできる】Google Cloud で CI/CD パイプラインを構築

2024/04/18に公開

はじめに

CI/CD?それは美味しいの?。
こんにちは、クラウドエースの岸本です。
今回は、CI/CD パイプラインを構築します。
ゴールとしては、Cloud Run から提供される URL にアクセスすると、簡単なウェブページが表示されるようにします。
背景としては、Vertex AI Search x LINE シリーズで毎回手動ビルドしているのが面倒だったため、CI/CD パイプラインを構築しました。
では、早速構築していきます。

構成図は以下です。

【構成図】
0-1

対象読者

  • Google Cloud のサービスで CI/CD を構築してみたい方
  • CI/CD を美味しいと思っている方
  • Google Cloud が好きな方

やること・やらないこと

やること

  • CI/CD パイプラインの構築
  • 簡単なウェブページをブラウザ上に表示する

やらないこと

  • ウェブページのデザイン
  • 詳細な機能の説明

目次

以下の手順で進めていきます。

    1. 概要説明
    1. ローカルにてソースコードを作成
    1. Artifact Registry とサービスアカウントの作成
    1. Cloud Build の設定(リンク、トリガー)
    1. Cloud Run にデプロイ

1. 概要説明

今回構築する CI/CD パイプラインと主な Google Cloud プロダクトについて少しご説明します。

  • CI と CD
    CI とは、Continuous Integration の略で、継続的な統合を意味します。
    CD とは、Continuous Deployment で、継続的なデプロイを意味します。
    継続的にコードを統合して、継続的にデプロイしようという考え方です。
    詳細は、こちらを参照してください。

  • CI/CD パイプライン
    CI/CD パイプラインとは、ソフトウェア開発プロセスにおいて、コードのビルド、テスト、デプロイを自動化するためのプロセスです。
    今回は、Google Cloud のサービスである Cloud Build を使用して CI/CD パイプラインを構築します。
    CI/CD パイプライン構築のメリットとして、開発の速度を向上させることができます。

  • Cloud Build
    Cloud Build は、Google Cloud のマネージド型のビルドサービスです。
    Cloud Build を使用することで、コードのビルド、テスト、デプロイを自動化することができます。
    Cloud Build から様々なプロダクトを対象としてデプロイすることができますが、今回のケースでは、Cloud Run を対象としてデプロイします
    Cloud Build のリポジトリは、第 1 世代、第 2 世代があり、今回は第 2 世代を使用します。
    世代の違いは、弊社のテックブログまたは、公式ドキュメントを参照してください。

  • Cloud Run
    Cloud Run は、コンテナ化されたアプリケーションを簡単にデプロイできるサービスです。
    Cloud Run は、サーバーレスであり、コンテナのスケーリングを自動で行うため、コストを抑えることができます。

2. ローカルにてソースコードを作成

ここでは以下の順で進めていきます

  • 2-1. リポジトリの作成
  • 2-2. ローカルにてソースコードを作成

構成図では以下の部分になります。
【構成図】
0-2

2-1. リポジトリの作成

まずは、リポジトリを作成します。
Cloud Build リポジトリは、Gitlub, GitHub, Bitbucket などのリポジトリと連携することができます。
今回は、GitHub と連携します。
適当に GitHub リポジトリを作成し、ローカルにクローンします。
ブランチも作成しておきます。

# リポジトリをクローン
$ git clone URL

# develop ブランチを作成
$ git checkout -b develop

これで、リポジトリ、ブランチの作成は完了です。
次に、ローカルにてソースコードを作成します。

2-2. ローカルにてソースコードを作成

今回は、簡単なウェブページを作成します。
ディレクトリ構成は以下の通りです。

.
├── Dockerfile
├── index.html
└── cloudbuild.yaml

それぞれの役割は以下の通りです。

  • Dockerfile は、Docker イメージをビルドするためのファイルです。
  • index.html は、ウェブページを表示するためのファイルです。
  • cloudbuild.yaml は、Cloud Build でビルドする手順を記述するファイルです。
    記述してある手順は、Docker イメージをビルドし、Artifact Registry にプッシュし、Cloud Run にデプロイする手順です。

では、それぞれのファイルを作成していきます。

ソースコードは以下の通りです。

Dockerfile
# Pythonイメージをベースにする
FROM python:3.9-slim

# 作業ディレクトリを設定
WORKDIR /usr/src/app

# index.htmlを作業ディレクトリにコピー
COPY index.html .

# ポート8080を開放
EXPOSE 8080

# http.serverモジュールを使ってHTTPサーバを起動
CMD ["python", "-m", "http.server", "8080"]
index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Simple HTML Page</title>
  </head>
  <body>
    <h1>何か困ったら岸本に相談してください。</h1>
    <h1>岸本も困ったら上司に相談しますので。</h1>
  </body>
</html>
cloudbuild.yaml
steps:
  # Build the container image
  - name: "gcr.io/cloud-builders/docker"
    args:
      [
        "build",
        "-t",
        "asia-northeast1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/my-image:latest",
        ".",
      ]
  # Push the container image to Container Registry
  - name: "gcr.io/cloud-builders/docker"
    args:
      [
        "push",
        "asia-northeast1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/my-image",
      ]
  # Deploy container image to Cloud Run
  - name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
    entrypoint: gcloud
    args:
      [
        "run",
        "deploy",
        "my-image",
        "--image",
        "asia-northeast1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/my-image:latest",
        "--platform",
        "managed",
        "--allow-unauthenticated",
        "--ingress",
        "all",
        "--region",
        "asia-northeast1",
        "--project",
        "${PROJECT_ID}",
        "--quiet"
      ]

logsBucket: "GCS_BUCKET_NAME"
serviceAccount: "projects/${PROJECT_ID}/serviceAccounts/ca-build-cicd@${PROJECT_ID}.iam.gserviceaccount.com"
options:
  logging: GCS_ONLY

以上がソースコードです。
cloudbuild.yaml の記述方法はこちらのドキュメントに記載してあります。
コマンドの詳細は、こちらのドキュメントを参照してください。

次に、Artifacts Registry とサービスアカウントの作成を行います。

3. Artifact Registry とサービスアカウントの作成

Dokcer イメージを保存するためのレジストリである Artifacts Registry と、サービスアカウントを作成します。
Artifacts Registry は、Docker イメージを保存するためのレジストリです。
サービスアカウントは、Cloud Build 用のサービスアカウントです。
Cloud Build の API を有効にするとデフォルトでサービスアカウントが作成されますが、不必要な権限を持っています(デフォルトサービスアカウントの権限一覧)。
これは、最小権限の原則に反しているため、サービスアカウントを作成し、必要な権限のみを付与します。
また、2024 年 4 月 29 日以降、Cloud Build のサービスアカウントの変更が行われるため、Cloud Build 用のサービスアカウントを作成することがより重要になります。

ここでは、以下の順で進めていきます。

  1. Artifacts Registry でリポジトリを作成
  2. サービスアカウントの作成と権限付与

【構成図】
0-3

3-1. Artifacts Registry でリポジトリを作成

まずは、Artifacts Registry でリポジトリを作成します。
具体的には、Cloud Buildでビルドしたイメージを格納するリポジトリ『my-docker-repo』を作成します。
コンソール画面から、Artifacts Registry を選択し、リポジトリを作成します。

項目
名前 my-docker-repo(任意)
形式 Docker
モード 標準
ロケーションタイプ asia-northeast1(東京)

リポジトリが作成されると、リポジトリの画面が表示されます。

【コンソール画面】
4-1

3-2. サービスアカウントの作成と権限付与

次に、サービスアカウントを作成し、今回使用するサービスに必要な権限を付与します。
今回必要な権限は、下の表、ロールに記載しています。
サービスアカウントの作成は、コンソール画面から行います。
コンソール画面からサービスアカウント作成がわからない方は、こちらを参照してください。
項目は以下のように設定します。

項目
名前 sa-build-cicd(任意)
ID sa-build-cicd(任意)
ロール Cloud Build サービス アカウント
ロール Cloud Run 管理者
ロール サービス アカウント ユーザー
ロール ログ書き込み
(省略可)体験記

最小権限の原則に従い、Cloud Build 用のサービスアカウントを作成しました。
ここでは、ログ書き込みService Account User の権限について説明します。
上記の構成図でイメージできた方は読み飛ばして頂いても問題ありません。
はじめに、ログ書き込みについてです。

  • ログ書き込み
    Cloud Build がログを書き込むために必要な権限です。
    ユーザー独自で作成したサービスアカウントを使用する場合、ログ書き込み権限を付与する必要があります。
    また書き込むためのログバケットを用意&指定する必要があります
    これが cloudbuild.yaml に logsBucket が記述されている理由です。
    デフォルトのサービスアカウントを使用する場合は、すでに持っているため、不要です。

次に、Service Account Userについてです。

  • Service Account User
    これがないと、以下のエラーが出ました。
Step #2: ERROR: (gcloud.run.deploy) PERMISSION_DENIED: Permission 'iam.serviceaccounts.actAs' denied on service account 123456789-compute@developer.gserviceaccount.com (or it may not exist).

エラーの理由は、Cloud Build のサービスエージェントに対する権限が不足しているためです。
Cloud Build 用のサービスエージェントはCloud Build が他の Google Cloud サービスのリソースにアクセスするために使用されます
今回は、作成したサービスアカウントが Cloud Build のサービスエージェントとして使用されるため、Service Account User 権限を付与する必要があったのです。

コンソール画面、[IAM と管理]から、Google 管理のサービスアカウントを一覧を見ていただければ、Cloud Build のサービスエージェントとサービスアカウントがあることが確認できます。

以上で、リポジトリ、サービスアカウント作成と権限付与は完了です。
次に、作成した cloudbuild.yaml を検知するよう、Cloud Build でトリガーを設定していきます。

4. Cloud Build の設定(リンク、トリガー)

以上で、Cloud Build の事前準備が完了しました。
これから、Cloud Build と GitHub リポジトリをリンクし、トリガーを設定していきます。
ここでは、以下の順で進めていきます。

    1. Cloud Build と GitHub リポジトリのリンク
    1. Cloud Build のトリガーを設定

【構成図】
0-3

Cloud Build と GitHub リポジトリをリンクし、Cloud Build のトリガーを設定します。
そうすることで、GitHub リポジトリに push された際に、Cloud Build が実行されるようになります。
トリガーを呼び出すイベントとして、あるブランチに push新しいタグを pushpull Requestを作成などがあります。
今回は、GitHub リポジトリの develop ブランチに push された際に、Cloud Build が実行されるようトリガーを設定します。
トリガーの詳細は、こちらを参照してください。

4-1. Cloud Build と GitHub のリンク

はじめに、Cloud Build と GitHub をリンクします。
Cloud Build と GitHub をリンクすることで、GitHub リポジトリに push された際に、Cloud Build が実行されるようになります。

Cloud Build のコンソール画面から、リポジトリを作成します。
リポジトリから、[第 2 世代]を選択し、[ホスト接続を作成]をクリックします。

【コンソール画面】
3-1

接続構成は以下の通りです。

項目
リージョン us-central1
名前 GitHub(任意)

次に、今回使用する GitHub リポジトリを選択し、認証を行います。
認証が終わると、ホスト接続が作成されます。

【コンソール画面】
3-2

最後に、Cloud Build と GitHub リポジトリをリンクします。
[リポジトリをリンク]をクリックし、以下の画面のように[接続]と[リポジトリ]で GitHub のリポジトリを選択します。

【コンソール画面】
3-3

これで、リポジトリに対するイベントが Cloud Build に通知され、ビルドが実行されるようになります。

[リポジトリの画面]
3-4

4-2. Cloud Build のトリガーを設定

次にトリガーを作成していきます。
トリガーを作成することで、GitHub リポジトリの develop ブランチに push された際に、Cloud Build が実行されるようになります。
以下のように設定してみます。

項目
名前 任意
リージョン us-central1
イベント ブランチに push する
ソース 第 2 世代
リポジトリ リポジトリを選択
ブランチ ^develop$
サービスアカウント sa-build-cicd を選択

[トリガーの設定画面]
40

以上で、Cloud Build と GitHub リポジトリのリンク、トリガーの設定は完了です。

5. Cloud Run にデプロイ

それでは早速、CI/CD パイプラインを実行し、Cloud Run にデプロイしていきます。
Cloud Run にデプロイされるまでの順序は、cloudbuild.yaml に記述されています。
develop ブランチに push すると、Cloud Build が実行され、Docker イメージがビルドされ、Cloud Run にデプロイされます。
以下の順で進めていきます。

  • 5-1. Cloud Build の実行
  • 5-2. Cloud Run 確認

【構成図】
0-5

5-1. Cloud Build の実行

Cloud Build でビルドを実行します。
実行させるには、GitHub リポジトリに push する必要があります。
そのほかにも、Cloud Build トリガーのコンソール画面から手動でビルドを実行することもできます。
【実行ボタン】
4-0
今回は、まだ GitHub リポジトリに push していないため、前者で実行します。
では、ローカルから GitHub リポジトリに push していきます。

$ git add .
$ git commit -m "first commit"
$ git push origin develop

GitHub リポジトリに push すると、Cloud Build が実行されます。
ログは、Cloud Build のコンソール画面の[履歴]から確認できます。
[Cloud Build の履歴画面]
4-2
ビルドが成功すると、Cloud Run にデプロイされます。

5-2. Cloud Run 確認

Cloud Run にデプロイされたことを確認します。
Cloud Run のコンソール画面から、サービスを選択し、URL をクリックします。
【Cloud Run の画面】
4-5

【ウェブページ】
4-6

【Cloud Storage の画面 - Cloud Build のログが保存されている】
4-7

ローカルで index.html ファイルを編集し、GitHub リポジトリに push すると、Cloud Build が実行され、Cloud Run にデプロイされます。
編集した内容が先ほどの Web ページに表示されているかと思います。
これで、CI/CD パイプラインの構築は完了です。

まとめ

今回は、CI/CD パイプラインを構築しました。
私自身も、CI/CD は美味しいのか、というところから始めましたので、初めての方にもわかりやすいように解説しました。
サービスアカウントなど、初めて Google Cloud を使う方には難しいかもしれませんが、ドキュメントを参照しながら進めていただければと思います。
CI/CD パイプラインを構築することで、開発の速度を向上させることができます。
今後 LINE x Vertex AI で何かを作成する際に、CI/CD パイプラインを活用していきたいと思います。
以上で、CI/CD パイプラインの構築は終了です。
最後までご覧いただき、ありがとうございました。

Discussion