小さく安全なリリースを実現するために使える「フィーチャートグル」って何？年収は？彼女は？調べてみました！

この記事は[リンクアンドモチベーション Advent Calendar2021](https://qiita.com/advent-calendar/2021/mcs)の14日目の記事になります。

# これはなに？
最近、主にDevOpsの文脈で「フィーチャートグル」という言葉をよく聞くようになりました。直近、自分の担当するプロダクトでも実際にAWS AppConfigを利用したフィーチャートグルの仕組みを実装しました。
ただ正直、自分自身フィーチャートグルというものについてとても浅い知識しか持っていなかったので、この機にフィーチャートグルについて色々と調べてみました。
ふざけたタイトルをつけましたが、中身はいたって真面目です。

この記事では、フィーチャートグルの定義や、メリット/デメリット、トグルの分類などについて整理していこうと思います。
いろいろな記事を読んだのですが、特に以下の２記事は非常に参考になったので最初に記載しておきます。
[Feature Toggles (aka Feature Flags)](https://martinfowler.com/articles/feature-toggles.html#ImplementationTechniques)
[フィーチャーフラグ（Feature Flag）はなぜ必要なのか？](https://codezine.jp/article/detail/14114)

なおフィーチャートグルには、フィーチャーフラグ、フィーチャースイッチ、など様々な別名がありますが、本記事ではフィーチャートグルで統一したいと思います。

# フィーチャートグルとは何か

フィーチャートグルとは「コードを書き換えることなくシステムの振る舞いを変更できる」開発手法です。[^1]
一方で、もう少し定義を拡張して「アプリの再起動やコードのデプロイを伴わない」ことを特徴として含める記事[^2]もあります。

実態としてはフィーチャートグルというと、後者の特徴を持つものを指していることが多いのではないかと思いますが、厳密にはアプリ再起動/コードデプロイを伴うかどうか、はフィーチャートグルの定義から外れそうな気がします。

なので例えば、環境変数により機能のON/OFFを制御している場合、このトグルの切り替えにはアプリの再起動が必要になりますが、おそらくそれもフィーチャートグルの１つとして考えて良いでしょう。

[^1]: https://martinfowler.com/articles/feature-toggles.html
[^2]: https://docs.microsoft.com/ja-jp/dotnet/architecture/cloud-native/feature-flags


# フィーチャートグルのメリット/デメリット
フィーチャートグルのメリット/デメリットについては[フィーチャーフラグ（Feature Flag）はなぜ必要なのか？](https://codezine.jp/article/detail/14114?p=2)で詳細がまとめられています。ここでは要点のみ記載します。
## メリット
### 1. 開発体験の向上

フィーチャートグルを活用することで、トランクベースの開発/継続的デプロイメントが実現しやすくなり、開発者体験の向上が期待できます。
(トランクベース開発の詳細は、[この記事](https://cloud.google.com/architecture/devops/devops-tech-trunk-based-development?hl=ja)とかが参考になると思います。)
(継続的デプロイメントと継続的インテグレーション、継続的デリバリーとの違いは[こちらの記事](https://www.atlassian.com/ja/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment)が参考になります)

フィーチャートグルで開発中の機能をOFFに設定しておくことで、未完成の機能をどんどんメインブランチにマージしながら開発を進めることで、ブランチワークの複雑性を解消し、コードを常に最新の状態に保てます。

さらに、フィーチャートグルで新しい機能を出し分けられるようにしておくことで、デプロイとリリースの分離が実現できます。機能をOFFにした状態であらかじめ本番環境にデプロイし、裏で十分にテストしておけば、リリースが必要になったタイミングでトグルをONにすることでデプロイを伴わないリリースが可能です。

またこの形であれば、リリース後にバグが見つかった場合でも、トグルをOFFにするだけで機能を閉じることができ、被害を最小限に留めることが可能です。

### 2. 本番環境でのテストが可能になる

フィーチャートグルを活用することで本番環境でのテストが可能になります。

フィーチャートグルを利用することで、新機能の提供範囲や、柔軟な機能の出しわけが可能になります。これにより、一部のユーザーに対して新機能をベータ公開してユーザーからのFBを得たり、ユーザーをランダムに振り分けてA/Bテストを行ったりすることがやりやすくなります。
また、リリースのリスクを軽減するために、少数のユーザー群に先にリリースし、問題がないことを確認してから全体リリースをするカナリアリリースなども実現しやすくなります。
参考：[ABテスト,カナリアリリース,ブルー・グリーンデプロイの違い](https://qiita.com/ozota/items/4126d85073175f66cb41)

## デメリット
### 1. コード量の増加

フィーチャートグルを導入すると、トグルの取得、判定のためにある程度のコードを記述する必要があります。外部サービスを利用する場合は、外部ライブラリのインストールや初期化のためのコードが必要です。


### 2. フィーチャートグルの管理コスト
フィーチャートグルをしばらく運用していると、数がしだいに増えて管理が複雑になってきます。
どのトグルがどこに影響しているのかが把握できなくなってきたり、複数のトグル同士が依存してしまtたりすることで、運用ミスやバグの発生に繋がります。

後述しますが、これらのデメリットを回避するためにも、トグルの性質をきちんと把握して不要になったものは定期的に削除していくなどで、トグルが無駄に増えすぎないように注意する必要があります。


# フィーチャートグルの4つの分類
フィーチャートグルは「トグルの有効期間」と「トグルの切替がどれだけ動的か」の２軸によって以下の４つに分類されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/2661deb6-ab71-e78e-a35a-e0f947a8eb5b.png)


### Release Toggle

Release Toggleは主に、先ほどメリットとして述べたトランクベース開発/継続的デプロイメントを実現するためのトグルです。
Release Toggleを用いて開発中の機能をOFFにすることで、未完成の機能をメインブランチにマージしながら開発を進めることができます。これにより、「機能のリリースとコードのデプロイを分離する」ことが可能になります。

また、基本的にはRelease Toggleは静的です。あるリリースバージョンでのトグルの値はすべて同じです。

### Experiment Toggle

Experiment Toggleは、A/B テストを行ったりするために使用されます。ユーザーを特定のロジックによって振り分け、効果を比較することができます。

Experiment Toggleは、統計的に有意な結果を得るために同じ構成で一定期間設置し続ける必要があります。トラフィックパターンにもよりますが、数時間から数週間程度が目安です。Experiment Toggleはその性質上とても動的で、リクエストごとに値を判定します。

### Ops Toggle

Ops Toggleは、システムの動作の運用面を制御するために使用されます。パフォーマンスへの影響が不明確な新機能を公開する際にOps Toggleを導入し、必要に応じて運用者がその機能を本番環境で迅速に無効化するために使われます。

ほとんどのOps Toggleは比較的短期間で削除されます。新機能が問題ないことが確認できればこのトグルは用済みです。
しかしたまに、比較的長期間運用されるものもあります。これは、システムに負荷がかかっている時に、重要でない機能を閉じたりする際に利用されます。例えばECサイトで、人気製品の発売直前に、重要でない機能を意図的にOFFにすることで、主要な購買フローに影響が出ないようにする、などのユースケースがあるようです。

### Permission Toggle

Permission Toggleは、機能を特定ユーザーに絞って公開する際に使用されます。例えば、有料のお客様のみが利用できる「プレミアム」機能のようなものだったり、あるいは、社内ユーザーのみが利用できる「アルファ」機能と、社内ユーザーに加えてベータユーザーも利用できる「ベータ」機能を用意するケースです。

プレミアムユーザーにのみ公開される機能を管理する方法として使用される場合、パーミッション切り替えは他の機能の切り替えに比べて非常に長く使用される可能性があります。パーミッションはユーザー固有のものであるため、Permissioning Toggleはリクエストごとに決定され、動的なトグルとなります。


# フィーチャートグル運用上のテクニック
フィーチャートグルは非常に便利ですが、同時に複雑さも増します。フィーチャートグルの管理をやりやすくするために、いくつかのテクニックがあります。

### 適用されているトグル設定が分かるようにする
アプリのバージョン番号などのメタデータをどこかで確認できるようにする、というのはよくあることかと思います。同様の考え方をフィーチャートグルにも導入し、現状のトグル設定がどうなっているか確認できるように何かしらのメタデータを公開しておくと便利です。

### 構造化されたデータの利用
ベースとなるトグルの設定情報は、YAML形式などで保存し、ソースベースで管理するのが一般的です。
これらのファイルに、さらに分かりやすいコメントをつけておくことにより、後からみた時に何をしているトグルなのかがすぐにキャッチアップできます。

### 異なるタイプのトグルを別々に管理する
先に述べたように、フィーチャートグルには様々な種類があり、それぞれ異なる特徴を持っています。それぞれの種類に応じた管理方法で管理するのが良いと思われます。

例えばですが、比較的変更頻度が低いRelease Toggleは環境変数や設定ファイル、柔軟に提供範囲を変更するために利用されるPermission Toggleは後述するAWS AppConfigやFirebase Remote Configなどの独立して管理できる仕組みで管理する、などの使い分けがいいのかなと思っています。

### 定期的にトグルを削除する

前述したデメリットで挙げた通り、フィーチャートグルが増えてくると管理コストがかかります。そのため、定期的にトグルを棚卸しして不要なものは削除していく運用が求められます。
例えば、リリーストグルを新しく導入したら、必ずトグルの削除タスクをチームのバックログに追加するというルールを設けるなどして、できる限りトグルの数を少なく保つ努力が必要です。

# フィーチャートグルを導入するための外部サービス
フィーチャートグルを実際に導入するにあたっては、環境変数やconfigファイル、DB、各種ライブラリなど様々ですが、フィーチャートグルをサービスとして提供しているものもあります。今回はその中からいくつか自分が調べたものを紹介したいと思います。

### AWS AppConfig
AWS System Managerの機能の一つであるAWS AppConfigを利用することで、比較的簡単にフィーチャートグルを導入することができます。少し前まではトグルの構成情報を記載した設定ファイルを独立して管理するだけの感じだったのですが、つい最近、UIで簡単にトグルを切り替えられるような機能がリリースされていました。
参考： [AWS が AWS AppConfig 機能フラグのリリースを発表 (プレビュー)](https://aws.amazon.com/jp/about-aws/whats-new/2021/11/aws-appconfig-feature-flags-preview/)

### Firebase Remote Config
こちらはモバイルアプリがメインになるかとは思いますが、Firebaseでもフィーチャートグルが提供されています。こちらは、ベータ版ではありますがA/Bテストの機能も提供されています。
参考：[Firebase Remote Config](https://firebase.google.com/docs/remote-config)

### Launch Darkly
こちらは、フィーチャートグル管理の機能を提供するSaaSサービスになります。フィーチャートグル管理に特化しているサービスだけあって、かなり機能は豊富なようで、プランによってはトグルの変更を予約したり、ワークフローを設定したりすることもできるようです。
https://launchdarkly.com/


他にも、[こちらの記事](https://codezine.jp/article/detail/14662)でいくつかのサービスが紹介されています。

# 最後に
今回はフィーチャートグルについてまとめてみましたが、いかがでしたか？
フィーチャートグルのメリット/デメリットや、４つの分類、運用上のテクニックなどが分かりました！
とはいえ、まだまだ完全に理解できたとはいえないので、さらに勉強を重ねたいと思います。

もし間違っているところなどがあればコメント/リクエストいただけると助かります。

また、余裕があれば実際にAWS AppConfigを使ってフィーチャーフラグを実装する方法についてもどこかでまとめたいなと思います。
最後までお読みいただきありがとうございました！



## 参考記事
https://martinfowler.com/bliki/FeatureToggle.html
https://martinfowler.com/articles/feature-toggles.html
https://codezine.jp/article/detail/14114
https://docs.microsoft.com/ja-jp/dotnet/architecture/cloud-native/feature-flag
https://dxcriteria.cto-a.org/c22f875be0e043b18ec75b14bdfcb9b0
https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%B0%E3%83%AB