はじめに
こちらは バイセルテクノロジーズ Advent Calendar 2023 の18日目の記事です。
昨日は佐々木さんによるCodeDeployを使ってデプロイの仕組みを入れ替えた話でした。
こんにちは、開発2部の富澤です。
バイセルでは店舗買取システムStoreの開発しています。
Storeではチームメンバーの増加によって、フロントエンドの動作確認環境の数が不足しておりました。
その結果、コードレビューにかなりのコストがかかるという課題がありました。
この課題を解決するため、 プルリクエストごとに動作確認用の実行環境を立ち上げる仕組みをCloud Runを利用して作成しました。
今回はその方法を紹介します。
背景
Storeのフロントエンドでコードレビューを依頼する時は、以下のフローを取っていました。
- プルリクエストを作成
- GitHub Actionsの
workflow_dispatch
を利用して動作確認用の環境に手動でデプロイ - レビュアーが上記の環境で動作確認
しかしチームメンバーの増加に伴って、動作確認用の環境が既に使われている場合が増えてきました。
このような場合、レビュアーはコードレビューの度に以下の操作を繰り返す事になります。
- レビュー依頼が来る
- 作業中のタスクをstashし、作業を中断する
- localで動作確認する
- レビューが終わったら最新のstashをapplyして作業に戻る
その結果、レビュアーの動作確認コストが高くなっていました。
やったこと
そこで、Cloud RunとGitHub Actionsを利用しプルリクエストごとに専用の動作確認環境が作成されるようにしました。
加えて、プルリクエストとURLの紐付けが行われるようにしました。
これによって、レビュアーはリンクをクリックすれば即座に動作確認を実施できるようになります。
プルリクエストから専用の動作確認環境に飛べる
ブランチのチェックアウトとローカルサーバーを立ち上げる必要が無くなるため、 レビューコストを削減できるはずです。
具体的にやったことは主に以下の2つです。
- プルリクエスト作成時にCloud Runへデプロイ
- CORSエラー回避のためProxyを設定
プルリクエスト作成時にCloud Runへデプロイ
前提としてStoreではNext.jsとCloud Runを採用しています。
Cloud Runはサービスをデプロイすると自動でURLを生成する機能があります。 今回はこの仕組みを利用することにしました。
Cloud Runが生成するURLは、ドメインの先頭にサービス名がプレフィックスとして自動的に付与されます。
例えばサービス名をpr-3832
と指定してCloud Runにデプロイすると、以下のようなURLが生成されます。
※ URLの決定方法については今後変更される可能性があります。
URLはどのプルリクエストと紐づいているのか判別できる方が好ましいです。
よってサービス名はpr-プルリクエスト番号
という命名規則を採用しています。
GitHub Actionsではgithub.event.number
でプルリクエスト番号を取得できます。
これを利用してCloud Runへのデプロイ時にサービス名を指定します。
ワークフローファイルを抜粋したコードが以下になります。
on: pull_request: types: - opened[f:id:bst-tech:20231204173324p:plain] - synchronize jobs: deploy: name: Deploy to Test runs-on: ubuntu-latest steps: ... - run: |- gcloud run deploy \ --port 3000 \ --image "IMAGE_PATH" \ pr-${{ github.event.number }}
次にプルリクエストとURLの紐付けを設定します。 紐付けにはGitHub Actionsのenvironmentを利用します。
jobに対してenvironment名とURLを指定する事で設定が可能です。
jobs: deploy: name: Deploy to Test environment: name: test url: https://pr-${{ github.event.number }}-xxxxx-an.a.run.app
ここまでで、必要なインフラのリソースとプルリクエストへの設定が完了しました。
CORSエラー回避のためProxyを設定
しかし、このままでは1つ問題があります。
それはBEのAPIがCloud Runの作成したオリジンに対してCORSを許可していない事です。
そのためAPIとの通信時にCORSエラーが発生してしまいます。 これでは動作確認ができません。
そこで、CORSエラーを回避するためにProxyを経由したAPIリクエストを行います。 Proxyの実装にはNext.jsのAPI Routesとnext-http-proxy-middlewareというライブラリを利用しました。
pages/api/[...all].ts
に以下の設定を記述します。
const proxy = (req: NextApiRequest, res: NextApiResponse) => { return httpProxyMiddleware(req, res, { target: "https://example.com", changeOrigin: true, pathRewrite: [ { patternStr: "^/api/proxy", replaceStr: "", }, ], }); };
上記の設定すると、例として以下のようにAPIリクエストがProxyされます。
- クライアント: 相対パスで
/api/proxy/hoge
を指定してリクエスト - Proxy:
https://example.com/hoge
にAPIリクエスト
これによってCORSエラーを回避し、APIとの通信ができるようになりました。
結果
やってよかったこと
自動的に環境が立ち上がるようになった事で、
ブランチのチェックアウトとローカル環境でのサーバー起動をスキップできるようになり、 レビューコストを削減する事できました。
また「〜環境を使ってもいいですか?」といったFE開発者間でのコミュニケーションを減らせた事も大きいと思っています。
FE開発者からの評判も良く、開発者体験の向上にも貢献できました。
今後の課題
課題としてはデプロイ速度の影響を受けやすくなった事が上げられます。
今回紹介した仕組みが導入された事によって、 Cloud Runへのデプロイが完了しないとレビュアーが動作確認を開始できない状態になります。
現状は数分で済んでいるので問題ありませんが、 今後デプロイが遅くなった場合、高速化を検討する必要がありそうです。
まとめ
今回はCloud Runを利用してプルリクエストごとに動作確認用の環境を作成する方法を紹介しました。
Cloud Runを利用していて環境の数が不足している場合、 非常におすすめな仕組みなので参考にしていただけると嬉しいです!
最後にBuySell Technologiesではエンジニアを募集しています。興味がある方はぜひご応募ください!
明日は飯島さんによる開発者の脳内リソースを食い潰さないという観点の設計です。お楽しみに。