この記事は、hacomonoアドベントカレンダー2024の2日目の記事です。
はじめに
こんにちは。プラットフォーム部所属のまこたすです。
本記事では、昨年プラットフォームチームで作成した基盤システムの1つであるfeature flagについてご紹介します。
記事は、前編 / 後編で分かれています。前編ではfeature flagについての理論と構築したシステム構築についてご紹介します。後半ではhacomonoアプリケーション側での利用 / 展開などの実践的な内容についてふれます。
本日 / 明日と連続でお送りしますので、どちらも最後までご覧いただけますと幸いです。
feature flagとは
最初にfeature flagとはどういったものかについて説明します。直訳すると「機能フラグ」というものですが、機能フラグがカバーするものとして以下の4つが紹介されています。
- Release Toggles(機能リリーストグル)
- Experiment Toggles(A/Bテストなどの実験的トグル)
- Ops Toggles(切り戻しなどの運用トグル)
- Permission Toggles(権限に基づく許可トグル)
Feature Toggles (aka Feature Flags) より参照
このように一言にfeature flag といっても実現したい切り替えがどういったものかによって若干性質が異なります。
hacomonoにおいての課題
hacomonoでfeature flagの導入を検討した背景に、以下のような課題感がありました。
- リリースの切り戻しに時間がかかる
- トランクベースの開発ができない
リリースの切り戻しに時間がかかる
リリースを行うのに1~2時間かかるといった問題がありました。ここでは詳細は省きますが、CI/CDがサービスの成長についていけてないために起こっていた問題になります。リリース作業後に問題が発覚した際は、リバートを行うのですが同じように時間がかかる状況でした。これは顧客に大きな影響を与えてしまう場合もあり、短い時間で切り戻したいという課題がありました。
トランクベースの開発ができない
hacomonoでは2週間に1回の頻度で本番リリース作業を行っています。機能のリリースにおいてもこのタイミングで行われます。また機能切り替えをするためのトグルがないため、トランクベースの開発がやりにくい状況でした。こうなるとfeatureブランチで早めに開発が完了してもそのブランチをマージできずに保守する必要があったり、〇〇環境向けのブランチみたいなものが生まれたりなど運用コストが高くなる課題がありました。
これらの問題への一つの打ち手として
- Release Toggles(機能リリーストグル)
- Ops Toggles(切り戻しなどの運用トグル)
を目的としたfeature flagの導入の取り組みをはじめました。
feature flagシステムの検討 / SaaS or 内製
人的リソースに限りがあるため、SaaSを使えるところは活用して運用負荷を下げていきたいところではあります。調べると高機能なfeature flag SaaSもあるようでしたが、今回は内製という方針をとりました。
なぜ内製か
おもに4つの理由があります。
- 内部的に保持しているセグメント情報を利用したい
- フラグ配信対象が不定期に増える
- 高機能なfeature flagはMVPで必要ない
- 機能リリースという大事な機能を外部サービスに依存することへの懸念
内部で保持しているセグメント情報を利用したい
前項の課題では触れませんでしたが、開発者の声で機能のリリースにおいて一部Experiment Togglesに近い使い方をしたいというニーズがありました。具体的には基盤システムの内部で持っているセグメント情報に応じた機能展開を行いたいというものです。SaaSの場合でもこういったセグメントに基づくリリースをサポートしているものは多いですが、利用するにはhacomono内部で持っているセグメント情報を正確にSaaSに同期する仕組みを構築する必要がありました。
フラグ配信対象が不定期に増える
hacomonoのサービスは、お客様との契約完了後に テナント
というデータを作成することで利用できるようになります。このテナント情報は論理/物理的に別れた空間に作成されるため、SaaSの場合は設定は少し工夫をしないとうまくサービスの活用に乗れないという課題がありました。乗るための一つの方法としてセグメント情報をSaaS側へ同期させる必要がありますが、前項の通り正確性が求められます。
高機能なfeature flagはMVPで必要ない
SaaSでは、A/Bテスト・パーセンテージリリース・CDN対応など高度な機能が備わっています。これらの機能は魅力的ですが、hacomonoにおいてそれを使いたいフェーズではなく、(お金, 開発者へのレクチャーも含む)導入コストが高くつきそうでした。
リリースという大事な機能を外部サービスに依存することへの懸念
SaaSでは、フラグ情報の登録/更新/削除はWebコンソールまたはAPIで行われ、読み込み(配布)はCDNというアーキテクチャが多そうでした。
CDNはパブリッククラウドのCDNを利用している場合が多いため可用性が高いですが、Webコンソール / API部分はサービスのSLA準拠の可用性になっています。SLA自体はサービスによって明示的に公開されていない場合や都度変更されるなどの記載もありました。
hacomonoの場合、お客様とお約束をした上で特定の日に機能をリリースすることがあります。リリースの際にSaaS側に不具合があり機能が提供できないとお客様への不利益に繋がることも考えられるため、自身でハンドリングできるフラグ管理システムが必要だと考えていました。
主に上記のような背景から、内製で簡易的なフラグ配信システムをサクッと作るという判断に至りました。
アーキテクチャについて
簡易的な図ですが、以下が今回実装したフラグ配信システムの図になります。
ここからはざっくり処理の流れについて説明します。
- ①github repositoryにymlを登録して、github actionsでs3にアップロード
例: フラグ情報を記載したyml
# ルート要素がフラグ名を表す release-xxxx1: description: "ここにフラグの概要説明を記載する" default: false # 全顧客に適用するフラグのデフォルト値(true / false) overwrite: # デフォルト値を上書きしたい場合、その値と対象顧客を下位要素で設定 value: true # 下記顧客のみで上書きする値 tenants: # 上書き対象顧客の配列を設定 - tenant-1 # 対象顧客(1個目) - tenant-n # 対象顧客(n個目) release-xxxx2: description: "xxxx"
- ②s3へObjectがputされると、Lambdaがキックされます
- Lambdaは以下のような処理を行います。
- ③配信対象の顧客一覧を取得し、配布条件に応じたフィルタリングを行う
- ④SQSに対象顧客 / フラグ情報(yml)/ 配信日時の情報をenqueue
- Lambdaは以下のような処理を行います。
- ⑤ SQSがqueueを配るLambdaを呼び出す
- ⑥Lambdaが配信対象環境にhttpsでフラグを登録
- 何らかの理由でフラグの配信に失敗した場合は、SQSに再enqueueし、backoffで配信のリトライを繰り返す
- ⑦DBにフラグ情報を登録
- 配信日時がDBにある情報より古い場合は、処理を無視することで冪等な状態を担保している
上記のような仕組みになります。
フラグ情報はhacomonoサービスのDBに格納する形にしています。仮にフラグ配信部分が障害等で動かなくなったとしても、DBの情報を直接書き換えるという手段で機能のON/OFFが可能となっています。
今後の改善
今回作ったフラグ配信システムは必要最低限の機能での実現でした。そのためこの後の短期・中期スパンで以下のような取り組みを行っていく予定です。
- 開発チームへ浸透させる取り組み
- 開発における細かいユースケースに対応しDXを向上
- SaaS利用も含む高機能なfeature flagの導入タイミングの検討
最後に
先日自チームでリリースした機能の切り戻しにおいてフラグ配信システムを利用しました。これまで全環境の機能をOFFにするのに1時間前後掛かっていたのが7分で切り戻すことができ早速貢献してくれました。
本格的に開発チーム側へ機能利用の展開をしていくには利用方針の検討や、フラグが適用される対象を広げるなど様々な取り組みが必要になってきます。その取組みについて明日「hacomonoにおけるRelease Toggles 実践編」という内容でリーアキテクチャ&イネーブルメント部に所属しているさいもんさんにお話していただきます。お楽しみに!
後編はこちら
株式会社hacomonoでは一緒に働く仲間を募集しています。
エンジニア採用サイトや採用ウィッシュリストもぜひご覧ください!