monorepo構成のフロントエンドアプリをcloud build経由でvercelへデプロイする

はじめに

turborepoを使ったmonorepo構成でアプリを作っていて、その際に複数のフロントエンドのパッケージをcloud buildからそれぞれのvercelプロジェクトへデプロイしたかった。

一つのパッケージを変更した際に、他のパッケージのデプロイまで実行されると嫌なので、vercelのGithub連携はやめて、CI/CDからデプロイするようにした。

API側でGCP(compute engine)を使っている理由から、CI/CDでCloud Buildを採用した。

API側のデプロイの話

OGP imageNode.jsアプリをcloud buildからcompute engineへデプロイするNode.jsで作成したWebアプリケーションをcloud build上でビルドしてcompute engineへデプロイしたのでまとめました

アプリの構成

    apps/
        front/
            package.json
            ...
        admin/
            package.json
            ...
    package.json

monorepoを採用して複数個のフロントエンドアプリを一つのリポジトリで管理し、それぞれ別のサーバ(今回はvercel)へデプロイしています。
今回のアプリではサイトのUIを扱うfrontと管理画面のUIを扱うadminがあります。(実際には他にもapiなどのpackageがappsにある)


デプロイの流れ

  1. 変更を加えてGithubのmainへpush/merge
  2. Github(Cloud Buildと連携済)がpushをCloud Buildへ通知
  3. Cloud Buildが変更されたpackageをデプロイするためのトリガーを実行
  4. トリガーからvercelへdeploy 


デプロイの詳細

2. Github(Cloud Buildと連携済)がpushをCloud Buildへ通知

GithubとCloud Buildを連携すればpush/mergeが通知されるようになる

参考

OGP imageGitHubとGoogle Cloud Build の連携を試してみた! | by Yuki Iwanari | google-cloud-jp | MediumCI/CDしてますか?. “GitHubとGoogle Cloud Build の連携を試してみた!” is published by Yuki Iwanari in google-cloud-jp.

3. Cloud Buildが変更されたpackageをデプロイするためのトリガーを実行

Cloud Buildのトリガーの作成を作成する。

作成の際に「含まれるファイルフィルタ」にデプロイしたいパッケージのパスを追加する事で、対象のファイルに変更が加わった場合のみトリガーが実行されるようになる。 

例) apps/frontのデプロイ用トリガーの場合


4. トリガーがvercelへdeploy 

トリガーで実行するstepでvercel cliからプロジェクトへデプロイする。
この時に以下のVercelのsecret情報が必要になる。 

secret情報

  • VERCEL_TOKEN: アカウント毎に作成できるToken
  • VERCEL_PROJECT_ID: デプロイしたいprojecのID
  • VERCEL_ORG_ID: デプロイしたいprojectを所有しているuser或いはorganazationのID

これらはyamlに直書きしたく無いので、GCPのSecret Managerを使ってセキュアに取得する。

OGP imageSecret Manager  |  Secret Manager  |  Google CloudSecret Manager de Google Cloud te permite almacenar claves de API, contraseñas, certificados y otros datos sensibles con total seguridad.

Cloud Buildの構成

Cloud Buildのyamlファイルは以下の通り。

    steps:
     - name: 'bash'
        entrypoint: 'bash'
        args: 
        - -c
        - |
        mkdir -p .vercel
        touch .vercel/project.json
        echo '{"orgId":"'$$VERCEL_ORG_ID'", "projectId":"'$$VERCEL_PROJECT_ID_FRONT'"}' >> .vercel/project.json
        cat .vercel/project.json
        secretEnv: ['VERCEL_PROJECT_ID_FRONT','VERCEL_ORG_ID']
     - name: node:16.14.0
        entrypoint: npx
        args: ['npx','vercel','--prod','-t','$$VERCEL_TOKEN']
        secretEnv: ['VERCEL_TOKEN']
    availableSecrets:
     secretManager:
     - versionName: projects/{projectName}/secrets/VERCEL_PROJECT_ID_FRONT/versions/latest
        env: VERCEL_PROJECT_ID_FRONT
     - versionName: projects/{projectName}/secrets/VERCEL_ORG_ID/versions/latest
        env: VERCEL_ORG_ID
      - versionName: projects/{projectName}/secrets/VERCEL_TOKEN/versions/latest
        env: VERCEL_TOKEN
    options:
      logging: CLOUD_LOGGING_ONLY
    timeout: 1200s

まずstepの一つ目では、.vercel/project.json を作成し、SecretManagerから取得した $VERCEL_ORG_ID$VERCEL_PROJECT_ID を書き込む。

二つ目では $VERCEL_TOKEN をvercel cliのオプションに渡してdeployを実行。

  npx vercel --prod -t $$VERCEL_TOKEN 

vercelの管理画面でデプロイがされていることを確認


終わりに

かなり説明はしょったけど久しぶりに記事書けた.