mcpField
C
configuration-management

configuration-management

github.com/itallstartedwithaideaクラウド・DevOps4480 回インストール29 週間前に更新
リポジトリ

configuration-management について

実行中にアプリケーション設定を調整する開発者や運用担当者向けの、動的設定管理スキルです。集中ストレージ、変更通知、検証、キャッシュ、ロールバックを扱い、設定変更とデプロイを分離します。

主な機能

  1. 01設定スキーマと検証
  2. 02集中ストレージとバージョン管理
  3. 03プッシュ型の変更通知
  4. 04TTL付きクライアントキャッシュ
  5. 05設定バージョンのロールバック

活用シーン

  1. 01環境間の機能フラグ管理
  2. 02デプロイせずにレート制限を調整
  3. 03マイクロサービスの設定を一元管理
  4. 04インシデント対応時に旧設定へ復元

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/itallstartedwithaidea/agent-skills --skill configuration-management

インストール後、Claude Code で/configuration-managementを入力して読み込まれたか確認します。

詳細

設定管理

googleadsagent.ai™ による Agent Skills™ の一部です

説明

設定管理では、Nacos の設定管理パターンに着想を得た、ホットリロード機能を備える動的な設定を実現します。アプリケーションは一元管理されたストアから設定を取得し、変更通知を購読して、再起動せずに更新を適用します。これにより、従来の「設定変更のたびにデプロイする」サイクルがなくなり、機能フラグ、レート制限、動作パラメーターを実行時に調整できます。

静的な設定ファイル(.env、config.yaml)では、パラメーターを変更するたびにデプロイが必要になります。実際のトラフィックを処理する本番システムでは、これにより不要なリスクや遅延が発生します。動的設定では、デプロイ(コードの変更)と調整(パラメーターの変更)を分離できるため、運用担当者はデプロイパイプラインに手を加えることなく、レート制限の調整、機能フラグの有効化、認証情報のローテーション、ルーティングルールの変更を行えます。

このスキルでは、スキーマ定義と検証、一元管理されたストレージとバージョン管理、プッシュ型の変更通知、TTL を使用したクライアント側キャッシュ、任意の過去バージョンへのロールバックなど、設定のライフサイクル全体を扱います。設定変更は、コードのデプロイと同じ厳格さで監査可能なイベントとして扱います。

使用する場面

  • 複数の環境にまたがる機能フラグを管理する場合
  • デプロイせずにレート制限やスロットリングのパラメーターを調整する場合
  • A/B テストの設定を実装する場合
  • マイクロサービスアーキテクチャの設定を一元管理する場合
  • インシデント対応のための設定ロールバックをサポートする場合
  • テナントごとの設定を持つマルチテナントアプリケーションを構築する場合

動作の仕組み

sequenceDiagram
    participant App as Application
    participant Client as Config Client
    participant Store as Config Store (KV)
    participant Admin as Admin UI

    App->>Client: Initialize with schema
    Client->>Store: Fetch current config
    Store->>Client: Return config + version
    Client->>App: Apply config values
    Admin->>Store: Update config value
    Store->>Client: Push change notification
    Client->>Client: Validate against schema
    Client->>App: Hot-reload updated values
    Note over App: No restart required

設定クライアントは、一元管理されたストアと同期するローカルキャッシュを維持します。変更はロングポーリングまたは WebSocket 経由でプッシュされ、スキーマに照らして検証された後、再起動せずに実行中のアプリケーションへ適用されます。

実装

interface ConfigSchema {
  rateLimitPerMinute: { type: "number"; min: 1; max: 10000; default: 100 };
  featureFlags: {
    type: "object";
    properties: {
      newDashboard: { type: "boolean"; default: false };
      aiAssistant: { type: "boolean"; default: true };
    };
  };
  maintenanceMode: { type: "boolean"; default: false };
}

class ConfigClient<T extends Record<string, unknown>> {
  private cache: T;
  private version: number = 0;
  private listeners = new Map<keyof T, Set<(value: unknown) => void>>();

  constructor(
    private store: KVNamespace,
    private schema: ConfigSchema,
    private namespace: string
  ) {
    this.cache = this.buildDefaults(schema) as T;
  }

  async initialize(): Promise<void> {
    const raw = await this.store.get(`${this.namespace}:current`, "json");
    if (raw) {
      this.validate(raw as Partial<T>);
      this.cache = { ...this.cache, ...raw } as T;
    }
  }

  get<K extends keyof T>(key: K): T[K] {
    return this.cache[key];
  }

  async set<K extends keyof T>(key: K, value: T[K]): Promise<void> {
    this.validateField(key as string, value);
    const previous = { ...this.cache };
    this.cache[key] = value;
    this.version++;

    await Promise.all([
      this.store.put(`${this.namespace}:current`, JSON.stringify(this.cache)),
      this.store.put(
        `${this.namespace}:v${this.version}`,
        JSON.stringify({ from: previous, to: this.cache, timestamp: Date.now() })
      ),
    ]);

    this.notify(key, value);
  }

  onChange<K extends keyof T>(key: K, callback: (value: T[K]) => void): void {
    if (!this.listeners.has(key)) this.listeners.set(key, new Set());
    this.listeners.get(key)!.add(callback as (value: unknown) => void);
  }

  async rollback(targetVersion: number): Promise<void> {
    const snapshot = await this.store.get(
      `${this.namespace}:v${targetVersion}`, "json"
    ) as { from: T } | null;
    if (!snapshot) throw new Error(`Version ${targetVersion} not found`);
    this.cache = snapshot.from;
    await this.store.put(`${this.namespace}:current`, JSON.stringify(this.cache));
  }

  private notify<K extends keyof T>(key: K, value: T[K]): void {
    this.listeners.get(key)?.forEach(cb => cb(value));
  }

  private buildDefaults(schema: ConfigSchema): Record<string, unknown> {
    return Object.fromEntries(
      Object.entries(schema).map(([k, v]) => [k, (v as { default: unknown }).default])
    );
  }

  private validate(partial: Partial<T>): void { /* schema validation */ }
  private validateField(key: string, value: unknown): void { /* field validation */ }
}

ベストプラクティス

  • すべての設定キーについて、型、範囲、デフォルト値を定義したスキーマを作成します
  • 監査可能性とロールバック機能を確保するため、設定変更ごとにバージョンを付与します
  • 適用前に、設定変更をスキーマに照らして検証します
  • アプリケーションが更新にすぐ反応できるよう、変更通知を実装します
  • ストアの一時的な停止に備え、TTL を設定して設定をローカルにキャッシュします
  • シークレット(認証情報、API キー)は設定から分離し、シークレットマネージャーを使用します

プラットフォーム対応状況

プラットフォーム対応状況備考
Cursor完全対応設定スキーマとクライアント生成
VS Code完全対応JSON/YAML の設定編集
Windsurf完全対応設定に対応
Claude Code完全対応スキーマとクライアントコードの生成
Cline完全対応設定管理
aider部分対応コードレベルのサポートのみ

関連スキル

キーワード

configuration-management hot-reload feature-flags dynamic-config nacos config-versioning rollback schema-validation


© 2026 googleadsagent.ai™ | Agent Skills™ | MIT License

コメント