🎅

BacklogのGitでもCloud Runに継続的デプロイしたい

2024/12/21に公開

ちょっと早いけどメリークリスマス。もっと早いけどハッピーニューイヤー。

この記事は3-shake Advent Calendar 2024の21日目の記事です。

はじめに

BacklogのGitリポジトリでCloud Runサービスに継続的デプロイする手順をまとめてます。

背景

Cloud Runで動作するアプリケーションのコードをBacklogのGitリポジトリで管理する案件がありました。しかし、Google CloudのCI/CDサービスであるCloud BuildはBacklogのGitリポジトリに対応していません。
それでもCI/CDを導入したかったので、対応方法を調査しました。

やりたいこと

とりあえず、mainブランチにマージされたらCloud Runにデプロイされるようにしたい。

手順

特定のリポジトリのmainブランチにマージされたらCloud Runにデプロイされる仕組みを構築していきます。
Backlog WebhookとCloud Buildを使います。

大きく以下の手順が必要です。

- ssh認証鍵の設定
- Cloud Buildトリガーの設定
- Backlog Webhookの設定

これを構築します。

詳しく見ていきます。

ssh認証鍵の設定

Cloud Build(後述)からBacklogのGitリポジトリにアクセスするために、ssh認証鍵を設定します。
このドキュメントを参考にして作成していきます。
https://cloud.google.com/build/docs/access-github-from-build?hl=ja

1. SSH 認証鍵を作成する

ssh-keygen -t rsa -b 4096 -N '' -f id_backlog_cicd_sample -C ''

2. シークレット マネージャーに秘密 SSH 認証鍵を保存する

Cloud Buildから安全に秘密鍵を参照したいので、シークレットマネージャーに作成した秘密鍵を保存しておきます。
▶️手順はこちらを参考にしてください。

3. 公開鍵をBacklogに登録する

▶️手順はこちらを参考にしてください。

ssh認証鍵の準備はこれで完了です。

Cloud Buildの設定

Cloud Buildのトリガーを作成します。
Cloud Buildとは、Google CloudのサーバーレスCI/CDプラットフォームです。詳しいことは公式ドキュメント[1]や以下を参照ください。
https://blog.g-gen.co.jp/entry/ci-cd-pipeline-with-cloud-build

BacklogのWebhook(後述)がここで設定したトリガーを作動させてCloud Runにデプロイが走るようになります。

トリガーを作成していきます[2]
まずは以下を設定します。

1. 名前とリージョンを設定する

2. イベントで「Webhookイベント」を選択する

3. シークレットを作成してWebhook URLを取得する

シークレットを作成します。


Webhook URLを表示(少しだけ時間かかるかも)して、URLを控えておいてください。BacklogでこのURLを使用します。

4. ソースは空のままにする

5. Cloud Buildのビルド構成ファイルを記述する

今回は、DockerイメージからCloud RunにデプロイするのでリポジトリにDockerfileがあることを前提にしています。
また、インラインYAMLで直接構成を記述します。

こちらを参考にしています。
https://cloud.google.com/build/docs/access-github-from-build?hl=ja#configure_the_build
$_COMMIT_SHAには次に説明する手順で設定するBacklogから送られてくるコミットハッシュ値が入ります。
適宜修正して貼り付けてください。

options:
  logging: CLOUD_LOGGING_ONLY
  env:
    - DOCKER_BUILDKIT=1
steps: 
# sshの設定
- name: 'gcr.io/cloud-builders/git'
  secretEnv: ['SSH_KEY']
  entrypoint: 'bash'
  args:
  - -c
  - |
    echo "$$SSH_KEY" >> /root/.ssh/id_rsa
    chmod 400 /root/.ssh/id_rsa
    ssh-keyscan -t rsa <SPACE ID>.git.backlog.com > /root/.ssh/known_hosts
  volumes:
  - name: 'ssh'
    path: /root/.ssh

# 設定したsshの鍵を使ってリポジトリをクローン
- name: 'gcr.io/cloud-builders/git'
  id: clone-repo
  entrypoint: 'bash'
  args:
    - '-c'
    - |
      # リポジトリが存在するか確認(Cloud Buildがキャッシュしてくれるので)
      if [ -d "<リポジトリ名>" ]; then
        echo "Directory '<リポジトリ名>' already exists. Performing git pull..."
        cd <リポジトリ名>
        git pull
      else
        echo "Cloning repository..."
        git clone <リポジトリURL>
      fi
  volumes:
  - name: 'ssh'
    path: /root/.ssh

# Dockerイメージのビルド(mainブランチの内容で)
- id: build
  name: 'gcr.io/cloud-builders/docker'
  dir: cicd-sample
  args: ['build', '-t', asia-northeast1-docker.pkg.dev/$PROJECT_ID/backlog-test/backlog-sample:$_COMMIT_SHA, '.']

# Dockerイメージのpush
- id: push
  name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'asia-northeast1-docker.pkg.dev/$PROJECT_ID/backlog-test/backlog-sample:$_COMMIT_SHA']

# Cloud Runへのデプロイ
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: gcloud
  args:
  - 'run'
  - 'deploy'
  - 'backlog-cicd-sample-run'
  - '--image'
  - 'asia-northeast1-docker.pkg.dev/$PROJECT_ID/backlog-test/backlog-sample:$_COMMIT_SHA'
  - '--region'
  - 'asia-northeast1'
  - '--port'
  - '<listern port>'

availableSecrets:
  secretManager:
  - versionName: <秘密鍵を保存したシークレットマネージャーリソース名>/versions/latest
    env: 'SSH_KEY'
    # リソース名の例
    # projects/xxxxxxxxx/secrets/BACKLOG_SSH_KEY

6. Backlogから送られてくる情報を変数に詰める

後述するBacklogのWebhookを設定すると、BacklogからCloud Buildのトリガーにリクエストが送信されます。そのリクエストのペイロードからコミットの情報などが取得でき、その情報を変数に詰めることができます。変数はビルド構成ファイルで使用したり、トリガーのフィルタリングに使用できます。
以下のように設定してください。

_CONTENT_REFなどはブランチ名などでフィルタリングしたいので設定しています。次の手順で使用します。

例)Backlogからのリクエストペイロード

Backlogからは以下のような形式で情報が送られてきます。

{
  "id":xxxx,
  "project": {
    "id": xxx,
    "projectKey": "XXXX",
    "name": "xxx",
    "chartEnabled": false,
    "subtaskingEnabled": false,
    "projectLeaderCanEditProjectLeader": false,
    "useWikiTreeView": true,
    "textFormattingRule": "markdown",
    "archived": false
  },
  "type": 12,
  "content": {
    "change_type": "create",
    "ref": "refs/heads/main",
    "repository": {
      "id": xx,
      "name": "<repository name>",
      "description": null
    },
    "revision_count": 1,
    "revision_type": "commit",
    "revisions": [
      {
        "rev": "<commit hash>",
        "comment": "<commit message>"
      }
    ]
  },
  "notifications": [],
  "createdUser": {
    "id": xxx,
    "userId": null,
    "name": "xxxx",
    "roleType": 1,
    "lang": "ja",
    "mailAddress": null,
    "nulabAccount": {
      "nulabId": "xxx",
      "name": "xxx",
      "uniqueId": "xxx"
    }
  },
  "created": "2024-12-05T02:43:41Z"
}

変数の記述方法は以下の記事がわかりやすかったです。
https://medium.com/google-cloud-jp/cloud-build-webhook-トリガーを始めよう-応用編-1fbfa17a2022

7. ブランチ名等でフィルタリングする

ここでは、Backlogのブランチ名・リポジトリ名をフィルタリングしてなんでもかんでもプッシュされたらトリガーが動かないようにします。
以下のように設定してください。リポジトリ名は適宜修正してください。

cicd-sampleリポジトリのmainブランチにプッシュされた時のみトリガーが動くように設定しています。

8. Cloud Buildが使用するサービスアカウントを選択する

Cloud Runへのデプロイのみを想定すると以下ロールを持っていれば足りるはずです。

Cloud Build サービス アカウント
Cloud Run デベロッパー
Secret Manager のシークレット アクセサー
Storage オブジェクト ユーザー
サービス アカウント トークン作成者
サービス アカウント ユーザー
ログ書き込み

Cloud Buildで必要な設定は以上です。実際にトリガーを作成してください。

BacklogでWebhookの設定

管理者またはプロジェクト管理者である必要があります。

ここでは、BacklogでWebhookを設定します。
https://support-ja.backlog.com/hc/ja/articles/360036147713-Webhook

Webhookとは、「課題の追加」や「課題にコメント」などのイベントがプロジェクト中で発生した際に、その情報をリアルタイムに指定されたURL(サーバー)へHTTP POSTする機能です。外部システムとの連携などに利用できます。

Webhookの設定をしていきます。
設定画面への辿り着き方はこちらを参照ください

1. Webhook名とWebhook URLを設定する

Webhook URLは先ほど控えておいたCloud BuildトリガーのWebhook URLを設定してください。

2. トリガーとなるイベントを設定する

今回はGitプッシュを選びます。

プルリクの追加や更新イベントなども選べるので、プルリク作成されたらCIするとかいろいろできそうです。

ここまでで全ての設定が完了です🎉

これでBacklogの対象リポジトリのmainブランチにpushしたりプルリクをマージしたりするとCloud Buildが実行されると思います。

トリガーが実行されている

Cloud Runがデプロイされている
また、別のブランチにプッシュしてもCloud Buildは実行されないと思います。

脚注
  1. https://cloud.google.com/build?hl=ja ↩︎

  2. https://cloud.google.com/build/docs/automate-builds-webhook-events?hl=ja&generation=2nd-gen ↩︎

  3. https://cloud.google.com/build/docs/automating-builds/github/connect-repo-github?hl=ja&generation=2nd-gen ↩︎

  4. https://cloud.google.com/build/docs/automating-builds/github/build-repos-from-github?hl=ja&generation=2nd-gen ↩︎

Discussion