概要
この記事は 一休.com Advent Calendar 2023 16日目の記事です。
RESZAIKO開発チームの松村です。
一休では各サービス毎に、開発中のサービスの動作を社内で確認できる環境があります。 それぞれmain(master)ブランチと自動的に同期している環境と、特定のブランチを指定して利用できる環境の2種類があります。
今回、RESZAIKOの新規サービス(予約画面)に対してブランチを指定してデプロイできる環境を作成したので、その方針と反省点と今後について記述していきます。
- 現在運用中の予約画面
開発環境を作る理由
一休では長らく、EKS上に複数の環境を用意して、ブランチを指定すると開発環境にデプロイするシステムが利用されてきました。 一般的にこのような環境を構築するのは以下のような理由が挙げられます。
- 動作確認
- マイクロサービスで、異なるブランチ同士の組み合わせで動作確認がしたい
- ローカルだと何故か再現しない
- デプロイがちゃんと動くか確認したい
- 他人と成果物の共有
- リリースできるほど動作に自信は無いが、ステークホルダーと内容を共有したい
本サービスではPrismaを利用してDBのスキーマをアプリのコードと同じリポジトリで管理しているため、 複数の新機能を平行して開発していく場合に開発環境が1つだと、DB定義が衝突したりして尚更大変です。 そこで、複数の開発環境を作成できるようにしました。
本サービスは基盤にGoogle CloudのCloud Runを使用しています。 Cloud Runは特に設定しなければアクセスがある時だけコンテナが起動するようになっているので、EKSを使用した場合よりスペックやコストをあまり気にせず環境を増やしていけます。
実現方法
サーバはCloud Runで動いていて、デプロイは Github Actionsで行っています。 そのため、開発環境用のGithub Actions Workflowを作成していきます。
デプロイを行うGithub Actions Workflowの作成
本記事の主旨から外れるので詳しく説明しませんが、 Google CloudにはGithub Actionsと連携してデプロイを行うための機能 が各種用意されているので、参考にしてWorkflowのyamlファイルを作成します。
name: backend.demo.create on: workflow_dispatch: inputs: name: required: true type: string description: "Environment name to deploy" jobs: build: runs-on: ubuntu-latest steps: - name: "Checkout" uses: actions/checkout@v3 # SecretからGCPの認証用のjsonを読み出す - id: "auth" uses: "google-github-actions/auth@v0" with: credentials_json: "${{ secrets.gcp-dev-service-accont-key }}" - name: "Set up Cloud SDK" uses: "google-github-actions/setup-gcloud@v0" with: install_components: 'alpha,beta' # 以下ビルド・デプロイの記述
Workflowの呼び出し
Workflowに workflow_dispatch
を定義することで、 外部からREST APIでWorkflowを呼び出すことができます。
開発環境用のアプリを作成して、そちらからREST APIで必要に応じてWorkflowを呼び出してあげます。
POST https://api.github.com/repos/test/test-repo/actions/workflows/backend.demo.create/dispatches Content-Type: application/json Accept: application/vnd.github+json Authorization: Bearer <TOKEN> X-GitHub-Api-Version: 2022-11-28 { "ref":"feature/branch-to-test", "inputs":{"name":"demo-1"} }
実装された運用
こんな感じのアプリを作成しました。
ブランチ名を入力して Deploy
を押すと、デモ環境に該当のブランチがデプロイされます。
いつ、誰が、どのブランチをデプロイしたかを記録するようになっています。
削除機能はまだ実装していないので、使い終わったらmainブランチを手動で適用する運用になっています。
反省と将来
折角Cloud Runを使っているのに、既存の他サービスの仕様に引きずられた実装にしてしまいました。 特に以下の点が良くないです。
- 設定ファイルをコピペして増やしていたので、環境を増やす毎に同じような設定ファイルが増える
- 環境毎に社内用のドメイン(
[env-name].dev.reszaiko.com
のような)を作っていたので、環境を増やす度にDNSとSSLの設定が必要になる
このため、気軽に環境を増減させる事が困難になっていて、既存の問題をそのまま引き継いでいます。
- 使わなくなった環境を戻し忘れてそのまま占有し続ける
- 空いている環境がない場合、他の環境を使っている人とコミュニケーションして融通してもらう必要がある
このままデプロイ環境を作るなら
ブランチデプロイ環境として、全てのブランチに対して自動的にデモ環境を作成、破棄するのが理想です。
コンテナのビルドやDBやサーバの用意、デプロイは既にGithub Actionsで行うようにしていますし、
開発環境へのアクセスはCloud Routerを利用して振り分けているため、 dev.reszaiko.com/[branch-name]/
のように環境毎のパスの追加もGithub Action上で構築できます。
また、特に開発環境を必要としない軽微な修正に対しても無制限に環境を作るのを防ぐために、以下の手段が考えられます。
dev-****
のように、特定のprefixを持つブランチに対して自動で環境を作る- 既存のデプロイ用UIを拡張して、環境数を増やしたり減らしたりできるようにする
前者はブランチが消えれば自動で環境が消えるので、使わなくなった環境が残ってしまうというよくある問題が解消できます。 後者はUI上で存在する環境の把握やアプリへのリンク、DBのリセットなど機能を追加する事ができて便利です。
開発環境を作らないと駄目なのか
そもそもブランチデプロイ環境が必要か、という問題もあります。
開発中のブランチを長期間利用していると本番環境との乖離が大きくなり、mainブランチにマージする際に入念なチェックが必要になります。 RESZAIKOの予約チームでは トランクベース開発 のように 頻繁にリリースする手法を導入するか議論していますが、 このような手法では開発中の機能はフィーチャーフラグを利用して出し分けるのが適しています。
RESZAIKOでは LaunchDarkly というフィーチャーフラグ機能を提供してくれるSaasを導入しているため、 コストをかけてブランチデプロイ環境を開発していくよりは、フィーチャーフラグを適切に利用する体制を整備し、開発環境はmainブランチと同期したものだけで運用していく方がいいかもしれません。
まとめ
使用している技術やサービスは日々新しい物が導入対象になるので、最適な開発手法というのはその時に合わせて検討する必要があります。 次に記事を書くときは「トランクベース開発に合わせたフィーチャーフラグの運用法」みたいなのが書けるように頑張ります。
一休では、共に働くエンジニアを募集しています。
カジュアル面談も実施しているので、お気軽にご応募ください。