フィーチャーフラグ

コードをデプロイした後に、機能の有効/無効を動的に切り替える仕組み

デプロイ運用

フィーチャーフラグとは

フィーチャーフラグ (Feature Flag / Feature Toggle) は、コードをデプロイした後に、設定値の変更だけで機能の有効/無効を切り替える仕組みである。未完成の機能をメインブランチにマージしつつ本番では無効にしたり、特定のユーザーにだけ新機能を公開したりできる。

Martin Fowler が 2010 年に「Feature Toggles」として体系化し、トランクベース開発やカナリアリリースの基盤技術として広く採用されている。

基本的な実装

// シンプルなフィーチャーフラグ
if (featureFlags.isEnabled('new-checkout-flow', { userId })) {
  return renderNewCheckout();
} else {
  return renderLegacyCheckout();
}

フラグの 4 分類

種類 寿命 動的性 用途
リリースフラグ 数日〜数週間 静的 未完成機能を隠す
実験フラグ 数週間〜数ヶ月 動的 A/B テスト
運用フラグ 長期 動的 キルスイッチ、サーキットブレーカー
パーミッションフラグ 長期 動的 ユーザーごとの機能制御

リリースフラグは短命で、機能が安定したら削除する。運用フラグは長期間残り、障害時に機能を即座に無効化するキルスイッチとして機能する。

AWS での実装パターン

SSM Parameter Store (シンプル)

import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm';

const ssm = new SSMClient({});
let cachedFlags: Record<string, boolean> | null = null;
let cacheExpiry = 0;

async function isEnabled(flagName: string): Promise<boolean> {
  if (Date.now() < cacheExpiry && cachedFlags) return cachedFlags[flagName] ?? false;

  const result = await ssm.send(new GetParameterCommand({
    Name: '/myapp/feature-flags',
  }));
  cachedFlags = JSON.parse(result.Parameter!.Value!);
  cacheExpiry = Date.now() + 60_000; // 1分キャッシュ
  return cachedFlags![flagName] ?? false;
}

AWS AppConfig (高機能)

AppConfig はフィーチャーフラグ専用の機能を持ち、段階的ロールアウト (10% → 50% → 100%)、ユーザーセグメント、ロールバックを統合管理できる。Lambda Extension として組み込めば、Lambda 関数から低レイテンシでフラグを取得できる。

段階的ロールアウト

新機能を全ユーザーに一斉公開するのではなく、段階的に公開する。

Day 1: 社内ユーザーのみ (1%)
Day 3: ベータユーザー (10%)
Day 5: 全ユーザーの半分 (50%)
Day 7: 全ユーザー (100%)

各段階でエラー率やパフォーマンスを監視し、問題があればフラグを無効化して即座にロールバックする。デプロイのロールバックより圧倒的に速い。

フラグの技術的負債

フィーチャーフラグの最大の問題は、不要になったフラグが削除されずに残ること。フラグが増えると条件分岐が複雑化し、テストの組み合わせが爆発する。

対策

  • フラグ作成時に「削除予定日」をメタデータに設定する
  • CI で期限切れフラグを検出して警告する
  • フラグの数に上限を設ける (例: アクティブなフラグは 20 個まで)
  • リリースフラグは機能安定後 1 週間以内に削除する

フィーチャーフラグについては関連書籍でも詳しく扱われている。

関連用語