本記事はUzabase Advent Calendar 2023の16日目の記事です。
概要
こんにちは 株式会社ユーザベース BtoB SaaS Product Team(以下 Product Team)の朴です。
普段の開発で大事なのは作ったものをデリバリーし続けることです。 いかに早くデリバリーできるか、いかに安定的にデリバリーし続けられるかなど、我々は工夫をし続けています。
今回はその中で、私が入社してこれまで経験し改善してきたCI/CDの進化についてです。
前提に
まず前提に、Product TeamではE2Eテスト・Unit Testの充実、トランクベース開発、XP、B/Gデプロイ、パイプラインの構築でCI/CDなどの概念は私が入社前から今にも続いている開発の文化になります。
各プラクティスの練度は上がったかも知れませんが、こういうものたちに取り組む・改善し続ける文化については変わってないですね。 こういうプラクティスの中で、Product Teamに合うパイプラインを構築していく旅の記事となります。
入社直後の状況
私が入社直後に配属されたチームでも同じくパイプラインがありましたが、いくつか辛いところがありました。 まず、パイプラインがものすごく遅く、不安定なところです。最初から最後まで流すのに1時間以上はかかるのでかなり辛かったです。
簡単に当時の課題をまとめると
- テスト関連
- テストの実行が長い
- テストが不安定
- 落ちたテストの再現性や調査が難しい
- k8sのバージョンアップが大変
- マイクロサービスを立てる時のパイプライン構築のコストが高い ...
などがありました。 こういう課題感は他のチームにも多少あったり、今でも完全になくせなかったりするものもありますが、徐々に改善してきてるのでどうやって改善してきたかをご紹介します。
テスト関連
テストの安定化
CI/CDにおいてテストはかなり大きい部分だと思います。素早くデリバリーをするにはテストの実行も早くないといけないし、安定的にデリバリーするにはテスト自体も安定的でないといけないですよね。
そのため、テストに関しての改善は永遠に続きますが、私がまず大事に思ってやっているのはテストデータの独立性を高める ことです。 E2Eテストのテストデータの独立性を高めるということでテスト同士で依存がなく、いつどのテストをどう流してもテストが成功するような状態を作ることができます。
しかし、テストデータの独立性を上げると、そのテスト専用のテストデータがあるということになります。 言い換えると、テストが流れる前に他のテストが流れて、データが書き換わると必ず失敗するということですね。 そのため、独立性の高いテストは直列に実行しないといけないです。
全部テストを直列で流しては、プロダクトが大きくなっていくと線形的にテストの実行時間が長くなります。 これを解決するためには、やはりテストを並列で回していく必要があります。
これはテスト環境も独立性を高めることで解決しています。
具体の実現方法に関しては弊社のUzabase Advent Calendar 2023の8日目の記事に他のものたちも含めて書いてありますので是非ご覧ください。
テストのデータの独立性を担保すると、テストの再現性・安定性も上がるし、もしテストが失敗した際の調査にもすごく役立ちます。
テストデータの独立性を上げるのは当たり前のように思えますが、プロダクトが大きくなってくる際にはしっかり意識していかないと思わずテスト同士に依存ができてテストを足したり、書き換えるのにコストがかかる状況になりがちなのでしっかり意識してテストの質を担保するようにしています。
k8s関連の課題
テスト環境をk8s上に作ってますが、いくつかの課題がありました。
まず改善したかったポイントは、テスト環境にテスト対象のサービスをデプロイする際に、パイプラインが直接kubectlコマンドでclusterにデプロイしてた ところですね。 パイプラインがk8sの環境に繋がっていて、パイプライン上でdeploymentやserviceを直接立てていたので、k8sのアップグレードがしにくかったり、そもそも下手に触ると本番環境が壊れてしまう恐れもあるので、何か加える際にはヒヤヒヤしてました。
ここら辺はGitOpsに変えることで改善しています。 パイプラインが直接デプロイをするのではなく、Gitにデプロイしたいマニフェストを吐き出し、それをArgoCDを使ってデプロイするという流れです。
skaffold、ArgoCDを組み合わせてGitOpsを実現しています。
skaffold自体の説明も弊社のブログをご覧ください!skaffoldのおかげでGitOpsも良いし安くなり、ローカル開発時の開発者体験も向上しました。
こうすることで、パイプラインと実際の環境を分離することができるので、お互いの影響も少なくなりました。
これから取り組むこと
私が現在担当しているプロダクトでは上記の全てが実現できてはいないです。とりあえず上記のものを実現することが目標ですね。
できれば遅くても開発が終わり、それが実際にE2E環境でE2Eが流れ切るまで10分ぐらいを目指したいと思っています。10分に特に深い意味はないですが、開発終わってちょっと休憩とってきたらフィードバックがあるような感じを目指したいですね。 パイプラインの結果も一つのフィードバックなので、できれば早く、できれば多くのフィードバックのために最強のパイプラインを構築していきます。
そのためにも上に書いた適切な並列化、テストの安定化は欠かせないのでこれらを駆使しながらもコストを抑えるようなパイプラインを作っていかないといけないですね。
また、この記事では紹介してないですが、最近はistioを使ってB/GデプロイをしてたものからArgo Workflowも使ったやり方に変えるなど、新しいツールも導入してるので新しい技術も活用できるチームにしていきたいと思います。 Argo Workflowは今回の記事では紹介できてないですが、Product Teamでも事例が増えてきてるのでまた他の記事で紹介できればと思います。