AWS AppConfig本番運用Vol1|再デプロイ不要のフィーチャーフラグと動的設定管理

目次

1. 動的設定/フィーチャーフラグの本番課題とAWS AppConfigの全体像

fig01: AWS AppConfig全体像(アプリケーション/環境/構成プロファイルで管理する設定・フィーチャーフラグを、デプロイ戦略でアプリへ配信し、Lambda extension/エージェントで取得する。コード再デプロイ不要の動的設定基盤)
fig01: AppConfig全体像 — 再デプロイ不要の動的設定/フィーチャーフラグ配信

本番環境でAWSを使ったサービスを運用していると、ある共通の課題に直面します。「新機能のフィーチャーフラグをONにしたい」「特定のAPIのレート制限値を変更したい」「障害発生時に特定の機能を即座に無効化したい」——こうした設定変更のたびに、コードを修正してビルド・テスト・デプロイのサイクルを回すのは、時間がかかるうえにリスクを伴います。

デプロイには必ず一定の時間がかかります。平均的なマイクロサービスのデプロイは数分から十数分を要します。問題が発生した際のロールバックも同様の時間を要します。さらに、デプロイという行為そのものが新たな障害の引き金になるリスクを常にはらんでいます。本来「設定の値を変えたいだけ」という操作に、このようなコストと危険を伴わせるのは、サービス運用における大きな摩擦です。

AWS AppConfigは、この問題を根本から解決するために設計されたサービスです。AWS Systems Manager配下のサービスとして、アプリケーションのコードを一切再デプロイすることなく、設定値やフィーチャーフラグをランタイムで安全に配信・切り替える仕組みを提供します。

本番運用で直面する設定管理の課題

設定値をソースコードに直接書き込む運用スタイルは、小規模なシステムではシンプルに機能します。しかし、サービスが成長し本番トラフィックを抱えるようになると、次のような課題が次第に顕在化します。

課題1: 設定変更に伴う再デプロイのリスク

設定値を変更するためだけに行うデプロイでも、通常のコードデプロイと同等のリスクを伴います。依存関係のある他のコンポーネントとの整合性確認、ステージング環境でのテスト、本番への段階的適用——これらのプロセスを経ずに「ちょっとした設定変更」を行うと、予期しない本番障害の引き金になります。かといって、すべてのプロセスを毎回踏むのは非効率です。

課題2: 環境変数による設定外部化の限界

環境変数やSSMパラメータによる設定外部化はある程度機能しますが、変更を反映させるにはプロセス再起動やデプロイが必要です。アプリケーション起動時に一度だけ読み込まれる環境変数は、本質的にランタイムでの動的変更に対応できていません。定期的なポーリングで変更を検知する仕組みを自前で実装できますが、バージョン管理・検証・段階的配信・監査ログを揃えると相当な実装コストになります。

課題3: フィーチャーフラグの管理複雑性

新機能を「フラグOFFでデプロイ→安全を確認後にフラグON」というパターン(フィーチャーフラグ)は、安全なリリース戦略として広く採用されています。しかし、フラグの管理は時間とともに複雑になります。フラグの定義・バージョン管理・段階的な有効化・問題発生時の即時無効化を一元管理する仕組みがなければ、フラグは散在してメンテナンスできなくなる「フラグ負債」を蓄積します。不要になったフラグを放置すると、コードが複雑化し将来の障害リスクにもなります。

課題4: 緊急時の設定変更速度

本番で障害が発生し、特定の機能を緊急で無効化したいとき、デプロイに数分かかっていては間に合いません。「設定を変えるだけで即座に機能を止められる」キルスイッチは、インシデント対応において非常に重要な手段です。再デプロイを必要としないキルスイッチを持つことが、MTTR(平均復旧時間)の大幅な短縮につながります。

AWS AppConfigとは何か

AWS AppConfigは、AWS Systems Managerの一機能として提供されるマネージドサービスです。アプリケーションコードとインフラ定義のどちらにも手を加えず、設定値とフィーチャーフラグをランタイムで動的に配信・切り替える専門サービスです。

AppConfigの核心的な価値は、「コードの再デプロイなしに設定を変更できる」という点にあります。設定変更とコード変更を分離することで、それぞれのリスクを独立して管理できます。機能追加はデプロイのサイクルで管理し、フラグのON/OFFや設定値の調整はAppConfigで即座に行う——この分離がサービスの俊敏性と安全性の両立を実現します。

サービスはAWS Systems Manager配下に位置しますが、独自の3階層モデル(Application/Environment/Configuration Profile)と専用のデプロイ戦略エンジンを持つ、独立した構成配信基盤として機能します。AWSが提供する検証機能(JSON Schema / カスタムLambdaバリデーター)と段階的デプロイ戦略(リニア/カナリア)により、不正な設定の誤配信や一括適用による障害拡大を防ぎます。

AppConfigは特定のユースケースに対して完成度の高いソリューションです。設定変更のたびに感じていた「デプロイの重さ」を取り除き、設定をコードから解放することで、チームの運用負荷を根本的に軽減します。

AppConfigが提供する主な機能

AppConfigの機能は大きく3つのカテゴリーに分類できます。

フィーチャーフラグ管理

フィーチャーフラグ型の構成プロファイルを使うと、フラグのON/OFFだけでなく、属性付きフラグ(数値・文字列・真偽値)やマルチバリアントフラグも管理できます。フラグに属性を持たせることで、「新機能を有効化したユーザーには割引率を15%に設定する」といった細かい制御が、コード変更なしに実現します。AppConfig Agent(バージョン2.0以降)を使えば、セグメント単位の段階的ロールアウトも可能です。

動的設定の外部管理

フリーフォーム型の構成プロファイルでは、任意のJSON/YAML/テキスト形式の設定を管理します。APIのレート制限値、タイムアウト設定、許可リスト、メンテナンスモードのフラグなど、運用中に変更が発生しやすい設定を一元管理できます。デプロイ前にJSON SchemaバリデーターやカスタムLambdaバリデーターで設定の正当性を検証するため、不正な設定が本番に配信されるリスクを排除できます。

安全なデプロイ戦略

設定変更を全ホストに一括適用するのではなく、リニア(均等ステップ)やカナリア(指数的拡大)のデプロイ戦略で段階的に配信できます。デプロイ中にCloudWatchアラームがALARM状態になると、自動的に前バージョンへロールバックします。この安全装置により、設定変更による障害の影響範囲を最小化できます。

デプロイ系サービスとの使い分け

AppConfigを正しく位置づけるために、AWSの既存サービスとの棲み分けを整理します。3つの層がそれぞれ異なる役割を担います。

CodeDeploy / CodePipeline / GitOps — コード/アーティファクトの配信

CodeDeployやCodePipeline、GitOpsツールはコードや実行バイナリ、コンテナイメージといったアーティファクトを環境へ配信します。新機能の追加、バグ修正、依存ライブラリのアップデートなど、アプリケーションそのものを変更する場合に使います。この操作は必ず再デプロイを伴います。コードの変更 = デプロイが必要というシンプルな対応関係です。

Terraform count / for_each — デプロイ時のIaCレベル切替

TerraformのHCL内でcount = var.enable_feature ? 1 : 0のように記述するフィーチャーフラグは、インフラのプロビジョニング時点での切替です。terraform applyを実行することで初めて反映されるため、インフラ変更のコンテキストに限定されます。アプリケーションのランタイムには影響しません。Terraformブランチ戦略の記事で詳細を扱っています。

AWS AppConfig — コードはそのまま、設定/フラグをランタイムで安全に切替

AppConfigはコードとインフラのどちらにも手を加えません。実行中のアプリケーションが定期的にAppConfigへポーリングし、設定の変更を検知したタイミングで新しい値を取得します。この取得はLambda extensionやAppConfig Agentが担い、ローカルキャッシュを活用することでAPIコストと遅延を最小化します。コードを再ビルドもデプロイもすることなく、フラグのON/OFFや設定値の変更が数十秒以内にランタイムへ反映されます。

AppConfigの全体像 — 3階層モデル

AppConfigの構成は、Application / Environment / Configuration Profileという3つの概念で管理されます。

Application: 設定をまとめる論理単位です。「ECサイト」「注文管理システム」「推薦エンジン」など、マイクロサービス単位やシステム単位でApplicationを作成します。複数のConfiguration Profileをまとめる親として機能します。

Environment: Applicationの配信先を表します。「本番(production)」「ステージング(staging)」「開発(development)」のように環境ごとにEnvironmentを作成します。各Environmentに対してCloudWatchアラームを紐付けることができ、デプロイ中にそのアラームがALARM状態になると、AppConfigが自動的に前バージョンへロールバックします。

Configuration Profile: 実際の設定データの定義と保管場所を指定します。フィーチャーフラグ型(AppConfigが提供するJSON構造で管理するフラグ専用のスキーマ)とフリーフォーム型(任意のJSON/YAML/テキスト)の2種があります。AppConfigホスト型ストレージ、S3、SSM Parameter Store、SSM DocumentをバッキングストアとしてProfileに紐付けられます。

デプロイ(Deployment)は、構成プロファイルの特定バージョンを、選択したデプロイ戦略に従って対象Environmentへ配信する操作です。バージョン管理が組み込まれているため、過去の設定への即座なロールバックが可能です。

Lambda extension / Agentによる設定取得の流れ

アプリケーションがAppConfigから設定を取得する方法は主に3種あります(詳細は§6で扱います)。推奨はLambda extensionとAppConfig Agentです。

Lambda extensionを使う場合、Lambda関数のサイドカーとして動作するextensionが設定をローカルにキャッシュします。関数コードはHTTP経由でhttp://localhost:2772にアクセスするだけで最新設定を取得でき、AppConfigへの直接APIコールは不要です。extensionがバックグラウンドでポーリングし、変更があれば自動的に更新します。関数ごとにAppConfigに接続する実装を書く必要がなく、設定取得の実装コストが最小化されます。

AppConfig Agentを使う場合は、ECS/EKS/EC2上のサイドカーコンテナまたはデーモンプロセスとして動作し、同様にローカルHTTPエンドポイント経由で設定を取得します。アプリケーションコンテナへの変更を最小限に抑えながら、動的設定取得の基盤を整備できます。

想定読者と本記事の構成

本記事はAWS Lambda、ECS、EKSを使ったサービスを本番運用している方を主な対象とします。特に次のいずれかに該当するシーンで役立てていただけます。

  • デプロイ頻度を下げずに、設定変更のリスクをコードデプロイから切り離したい
  • フィーチャーフラグを体系的に管理し、段階リリースやA/Bテストを安全に実現したい
  • 障害時のキルスイッチや動的設定変更によるインシデント対応速度を向上させたい
  • フラグ負債の蓄積を防ぎ、設定管理を一元化したい

AWSの基本操作やLambda/ECSの基本的な利用経験は前提とします。本記事はAppConfig固有の運用に集中し、Lambda/ECS/EKSの基礎やCI/CDの基本は既存の関連記事へ誘導します。

本記事Vol1では、AppConfigの全体像から始まり、構成階層(§2)、フィーチャーフラグ(§3)、動的設定・検証(§4)、デプロイ戦略・セーフガード(§5)、統合・運用・コスト(§6)、実戦パターン(§7)、アンチパターン・まとめ(§8)を順に扱います。

本シリーズVol1が扱うトピック(AWS AppConfig)

  • AppConfig基礎 — アプリケーション/環境/構成プロファイル/デプロイ戦略(§2)
  • フィーチャーフラグ — フラグ定義/属性付きフラグ/段階的ロールアウト(§3)
  • 動的設定 — フリーフォーム構成/JSON Schema・Lambda検証/バージョン管理(§4)
  • デプロイ戦略&セーフガード — プログレッシブ/リニア/カナリア/自動ロールバック(§5)
  • 統合・運用・コスト(Lambda extension/Agent)と実戦パターン(§6・§7)
デプロイ/IaCとの使い分け・棲み分け

  • CodeDeploy/CodePipeline/GitOps — コード/アーティファクトの配信(再デプロイ)
  • Terraform count/for_each のフィーチャーフラグ — デプロイ時のIaCレベル切替(既存記事)
  • AWS AppConfig — コードはそのまま、設定/フラグをランタイムで安全に切替(再デプロイ不要)
  • 本記事はAppConfig固有の運用に集中。CI/CD/IaCの基本は既存記事を参照

コード配信のCI/CDはこちら(CodePipeline/CodeDeploy本番運用)


2. AppConfig基礎 — アプリケーション・環境・構成プロファイル

fig02: AppConfigの構成階層(Application→Environment(本番/ステージング等)→Configuration Profile(フィーチャーフラグ型/フリーフォーム型)の3階層と、デプロイ戦略で環境へ配信する構造)
fig02: AppConfig構成階層 — Application/Environment/Configuration Profile

AWS AppConfigは、アプリケーションの設定とフィーチャーフラグをコードのデプロイなしに管理・配信するサービスです。Systems Managerのサブサービスとして提供されており、Application・Environment・Configuration Profileの3階層で設定を一元管理します。

2.1 Application — 設定を束ねる論理単位

AppConfigのApplicationは、関連する設定をまとめる論理コンテナです。ECサイト・決済サービス・注文管理システムといったサービス単位で作成するのが一般的です。

# Applicationと配下の構成プロファイルの関係
Application: ec-site
  ├── Configuration Profile: feature-flags(フィーチャーフラグ型)
  └── Configuration Profile: rate-limits  (フリーフォーム型)

Application: payment-service
  ├── Configuration Profile: feature-flags(フィーチャーフラグ型)
  └── Configuration Profile: fraud-config (フリーフォーム型)

1つのApplicationに複数のConfiguration Profileを持たせることができるため、フラグ管理と動的設定を同一アプリ配下で一元管理できます。マイクロサービスアーキテクチャでは各サービスごとにApplicationを作成し、それぞれが独自の設定ライフサイクルを持つ設計が適しています。

Applicationの作成はAWSコンソール・CLI・Terraform/CDKいずれでも可能です。名前は英数字とハイフン・アンダースコアを使用し、意味がわかる命名(ec-sitepayment-serviceorder-management)とします。

# AWS CLIでApplicationを作成する例
aws appconfig create-application \
  --name "ec-site" \
  --description "ECサイトの設定管理"

2.2 Environment — デプロイ先とCloudWatchアラームの紐付け

EnvironmentはApplicationが設定を配信するデプロイ先の環境を表します。ProductionStagingDevelopmentのように複数のEnvironmentを作成し、環境ごとに独立した設定ライフサイクルを持たせます。

Environmentの最も重要な役割はCloudWatchアラームの紐付けです。Environmentに1つ以上のCloudWatchアラームを紐付けると、デプロイ中にそのアラームがALARM状態になると自動的に設定のロールバックが実行されます(詳細は§5)。

# AWS CLIでEnvironmentを作成する例
aws appconfig create-environment \
  --application-id "APPLICATION_ID" \
  --name "Production" \
  --monitors '[
 {
"AlarmArn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm/api-error-rate",
"AlarmRoleArn": "arn:aws:iam::123456789012:role/AppConfigMonitorRole"
 }
  ]'

Environmentごとに異なるCloudWatchアラームを設定することで、本番環境はエラー率アラームを厳しく設定し、ステージング環境は緩やかな基準を適用するといった柔軟な運用ができます。Environmentを削除すると、そのEnvironmentへのデプロイ履歴も失われるため、命名と管理には注意が必要です。

また、EnvironmentはIAMポリシーのリソース指定にも使用できます。特定のEnvironment(本番のみ)への設定デプロイを特定のIAMロールにのみ許可するといった権限設計が可能です。

2.3 Configuration Profile — 構成プロファイルの2種類

Configuration ProfileはEnvironmentへ配信する設定の定義です。AppConfigではフィーチャーフラグ型フリーフォーム型の2種類があります。

① フィーチャーフラグ型(Feature flag type)

フラグのON/OFFと属性値を管理するプロファイルです。保管先はAppConfigホスト型のみ(S3やSSM Parameter Storeには保存できません)。AWSコンソールの専用UIでフラグを視覚的に定義できます。

フィーチャーフラグ型の主な機能:
– フラグの enabled(true/false)を管理
属性付きフラグ: 数値・文字列・真偽値の属性を持たせ、アプリが属性値を読んで挙動を制御
マルチバリアントフラグ: 条件に応じて異なる値を返す(A/Bテスト・段階リリース向け)
– AppConfig Agent連携でセグメント単位の段階的ロールアウトが可能

// フィーチャーフラグ型の設定JSON例
{
  "flags": {
 "new-checkout-ui": {
"name": "新チェックアウトUI"
 },
 "ai-recommendation": {
"name": "AIレコメンド機能",
"attributes": {
  "model-version": {
 "constraints": {
"type": "number",
"minimum": 1,
"maximum": 5
 }
  }
}
 }
  },
  "values": {
 "new-checkout-ui": {
"enabled": true
 },
 "ai-recommendation": {
"enabled": true,
"model-version": 3
 }
  },
  "version": "1"
}

属性付きフラグを使うと、ai-recommendation フラグが有効な場合でもモデルのバージョン番号をランタイムで切り替えられます。再デプロイなしにモデルの切り替えが可能なため、ML機能の段階的な本番投入に活用できます。

② フリーフォーム型(Freeform type)

JSON・YAML・テキストといった任意の形式で設定を管理するプロファイルです。フリーフォーム型では設定の保管先を選択できます。

保管先特徴
AppConfigホスト型AppConfig内部に保存。最もシンプル。バージョン管理込み
Amazon S3大きな設定ファイルや既存のS3管理設定に適する
AWS SSM Parameter Store既存のSSMパラメータを設定として活用する場合に適する
AWS SSM DocumentCloudFormationやSystems Manager Automationと連携する場合

SSM Parameter Storeの基本操作については、既存の関連記事を参照してください。本記事はAppConfig固有の構成モデルに集中します。

フリーフォーム型の使用例:
– レート制限値(1分あたりのリクエスト数上限)
– タイムアウト設定(外部APIへの接続タイムアウト)
– 許可リスト/拒否リスト(IPアドレス・メールドメイン)
– サーキットブレーカーの閾値

// フリーフォーム型の設定例(JSON形式)
{
  "rateLimits": {
 "apiRequestsPerMinute": 1000,
 "loginAttemptsPerHour": 10
  },
  "timeouts": {
 "externalApiMs": 3000,
 "dbQueryMs": 5000
  },
  "allowedDomains": ["example.com", "partner.co.jp"],
  "circuitBreaker": {
 "enabled": true,
 "failureThresholdPercent": 50
  }
}

2.4 デプロイ — 構成バージョンを環境へ配信

AppConfigにおけるデプロイとは、Configuration Profileの特定バージョンを指定したEnvironmentへ配信する操作です。コードのデプロイ(新しいアーティファクトの本番反映)とは異なり、設定のみを安全に切り替えます。

デプロイの流れ:
1. Configuration Profileで設定を編集し、新バージョンを作成
2. バリデーター(§4詳述)で設定の正確性を検証
3. デプロイ戦略を選択(即時/リニア/カナリア)
4. Environmentへ配信する
5. CloudWatchアラームを監視しながら段階的に配信

# AWS CLIでデプロイを開始する例
aws appconfig start-deployment \
  --application-id "APP_ID" \
  --environment-id "ENV_ID" \
  --deployment-strategy-id "STRATEGY_ID" \
  --configuration-profile-id "PROFILE_ID" \
  --configuration-version "3" \
  --description "レート制限値を1000→1500に変更"

デプロイの進行状況はコンソールやCLIでリアルタイムに確認でき、問題が発生した場合はデプロイを手動で停止またはロールバックできます。

2.5 バージョン管理 — 設定履歴とロールバック

AppConfigはConfiguration Profileのバージョンを自動管理します。設定を編集して保存するたびに新バージョンが作成され、全バージョンの履歴が保持されます。問題が発生した場合は特定バージョンを指定して即座にロールバックできます。

バージョン管理の特徴:
– 各バージョンに任意の説明を付与可能(変更内容を記録)
– バージョン番号は自動採番(1, 2, 3…)
– 任意バージョンへのロールバックはコンソール・CLIどちらでも可能
– CloudWatchアラーム連動の自動ロールバックにより障害時は前バージョンへ即座に復帰

# 特定バージョンにロールバックする例(バージョン2に戻す)
aws appconfig start-deployment \
  --application-id "APP_ID" \
  --environment-id "ENV_ID" \
  --deployment-strategy-id "AppConfig.AllAtOnce" \
  --configuration-profile-id "PROFILE_ID" \
  --configuration-version "2" \
  --description "バージョン2へ緊急ロールバック"

2.6 IAMロール — 保管先へのアクセス権限

フリーフォーム型でS3やSSM Parameter Storeを保管先として使用する場合、AppConfigサービスが保管先にアクセスするためのIAMロールが必要です。フィーチャーフラグ型(AppConfigホスト型のみ)の場合はIAMロールが不要です。

// S3保管先用IAMポリシーの例
{
  "Version": "2012-10-17",
  "Statement": [
 {
"Effect": "Allow",
"Action": [
  "s3:GetObject",
  "s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::my-config-bucket/appconfig/*"
 }
  ]
}

信頼ポリシーには appconfig.amazonaws.com をプリンシパルとして指定します。また、アプリケーション側(Lambda関数・ECSタスク)が設定を取得するためのIAMポリシーとしては、appconfig:GetLatestConfigurationappconfig:StartConfigurationSession の権限が必要です(§6で詳述)。

AppConfigの構成階層

  • Application — 設定をまとめる論理単位(アプリ/サービス単位)
  • Environment — デプロイ先(本番/ステージング/開発)。CloudWatchアラームを紐付け
  • Configuration Profile — フィーチャーフラグ型 / フリーフォーム型の2種
  • 構成データ保管先 — AppConfigホスト型 / S3 / SSM Parameter Store / SSM Document

3. フィーチャーフラグ — 定義・属性・段階的ロールアウト

fig03: AppConfigフィーチャーフラグの構造(フラグのON/OFF、属性付きフラグ(数値/文字列/真偽の属性値)、マルチバリアントフラグ、AppConfig Agentによるセグメント/ユーザー単位の段階的ロールアウト)
fig03: フィーチャーフラグ構造 — 属性付き/マルチバリアント/段階的ロールアウト

AWS AppConfigのフィーチャーフラグは、コードを再デプロイせずに機能のON/OFFと動作の切り替えを実現する設定管理機能です。「フィーチャーフラグ型」構成プロファイルを使用すると、アプリケーションの挙動を実行時に動的に変更できます。本節では、フラグ定義の基礎から属性付きフラグ、マルチバリアントフラグ、AppConfig Agentを活用した段階的ロールアウトまでを解説します。

3.1 フィーチャーフラグの基礎

フィーチャーフラグは「フィーチャーフラグ型」構成プロファイルとして作成します。フリーフォーム構成(任意のJSON/YAML)とは異なり、フラグ専用の管理UIと専用スキーマを持ちます。

フラグ定義の構造

最もシンプルなフラグはenabledフィールドのON/OFFだけを持つ形式です。

{
  "newCheckoutFlow": {
 "enabled": true
  },
  "darkModeDefault": {
 "enabled": false
  }
}

マネジメントコンソールから「フィーチャーフラグを作成」→フラグ名を入力→enabled初期値を設定する操作は数分で完了します。フラグはApplicationとEnvironmentの組み合わせ単位でデプロイされるため、本番環境だけOFFにする環境別制御も容易に実現できます。

アプリケーション側では、AppConfig AgentまたはLambda extensionが返す設定データを読み取り、フラグの値に基づいて処理を分岐します。コードには「もし新しいチェックアウトフローが有効なら」というif分岐だけを仕込んでおき、実際のON/OFF制御はAppConfigの設定変更で行います。これにより、コードフリーズ後でも本番フラグを切り替えることが可能です。

フィーチャーフラグ型の仕組み

フィーチャーフラグ型の構成プロファイルは、AppConfigが内部でJSONスキーマを持ちます。不正なフラグ定義(例: enabledに文字列を設定する)はコンソールレベルで拒否されるため、型の不整合による誤配信を未然に防止できます。

フリーフォーム構成との主な違いを以下の表に示します。

項目フィーチャーフラグ型フリーフォーム型
用途ON/OFF・属性付きフラグレート制限値/タイムアウト等の任意設定
スキーマAppConfigが内部管理JSON Schemaで独自定義(任意)
バリデーションコンソールで自動検証デプロイ前にvalidatorで検証

フィーチャーフラグの管理には「フィーチャーフラグ型」を選択し、任意の設定値には「フリーフォーム型」を使い分けることで、用途に適した検証とUIを活用できます。

3.2 属性付きフラグ

基本的なON/OFFに加えて、フラグに属性(Attribute)を付与すると、機能の有効/無効だけでなく挙動のパラメータを動的に制御できます。

属性の型と制約

AppConfigの属性付きフラグでは次の型がサポートされています。

  • 数値型(Number): レート制限の上限値や表示件数など整数・浮動小数点数の設定に使用します。制約として最小値/最大値を設定できます。
  • 文字列型(String): エンドポイントURLやメッセージテンプレートなどテキスト値の設定に使用します。列挙制約(許可値リスト)を定義して誤設定を防止できます。
  • 真偽値型(Boolean): サブオプションのON/OFFに使用します。親フラグのenabledとは独立して制御できます。

属性付きフラグの定義例を以下に示します。

{
  "recommendationEngine": {
 "enabled": true,
 "attributes": {
"maxRecommendations": {
  "constraints": {
 "type": "number",
 "minimum": 1,
 "maximum": 50
  },
  "value": 10
},
"algorithm": {
  "constraints": {
 "type": "string",
 "enum": ["collaborative", "content-based", "hybrid"]
  },
  "value": "hybrid"
},
"enableLogging": {
  "constraints": {
 "type": "boolean"
  },
  "value": true
}
 }
  }
}

この設定では、recommendationEngineフラグがONのとき、アプリはmaxRecommendations(最大10件)/algorithm(ハイブリッド方式)/enableLogging(有効)を一括で受け取ります。これらの値を変更したい場合、AppConfigコンソールまたはAPIで属性値を更新してデプロイするだけで、コードの変更は不要です。

属性付きフラグの実装パターン

アプリケーション側での取得・参照方法の例を以下に示します。

import boto3
import json

client = boto3.client('appconfigdata')

# セッション開始
session = client.start_configuration_session(
 ApplicationIdentifier='MyApp',
 EnvironmentIdentifier='Production',
 ConfigurationProfileIdentifier='FeatureFlags'
)

# 設定取得
response = client.get_latest_configuration(
 ConfigurationToken=session['InitialConfigurationToken']
)

flags = json.loads(response['Configuration'].read())

# 属性付きフラグの参照
rec_flag = flags.get('recommendationEngine', {})
if rec_flag.get('enabled', False):
 attrs = rec_flag.get('attributes', {})
 max_recs = attrs.get('maxRecommendations', {}).get('value', 5)
 algorithm = attrs.get('algorithm', {}).get('value', 'content-based')

実際の本番環境ではLambda extensionまたはAppConfig Agentを使用したキャッシュ取得が推奨です。上記はSDK直接取得の参考として示しています。

3.3 マルチバリアントフラグ

マルチバリアントフラグは、ユーザーの属性やコンテキスト条件に基づいて異なる設定値を返す仕組みです。同じフラグに対してユーザーセグメントごとに異なる挙動を設定でき、A/Bテストや段階リリースの基盤となります。

バリアントの定義

マルチバリアントフラグでは、各バリアントに条件と設定値のペアを定義します。条件に一致したバリアントの値がアプリに返ります。

{
  "checkoutFlow": {
 "enabled": true,
 "attributes": {
"flowVersion": {
  "constraints": {
 "type": "string",
 "enum": ["v1", "v2", "v3"]
  },
  "value": "v1"
}
 }
  }
}

AppConfig Agentを使用すると、ユーザーセグメント(セグメントIDやカスタム属性)に基づいて異なるバリアントを動的に返せます。例えば、ユーザーIDのハッシュ値に基づいてユーザーを自動的にグループAまたはグループBに割り当てる制御が可能です。

マルチバリアントとA/Bテストの実践

新しいUIコンポーネントをA/Bテストする場合の流れを示します。

  1. フィーチャーフラグ型構成プロファイルでuiVariantフラグを作成します。
  2. バリアントcontrol(既存UI)とバリアントtreatment(新UI)を定義します。
  3. AppConfig Agentのセグメント設定でユーザーの50%にバリアントtreatmentを配信します。
  4. CloudWatchでコンバージョン率やエラー率を計測し、効果を検証します。
  5. 検証結果に基づいてフラグを全ユーザーにtreatmentへ切り替えるか、controlに戻すかを判断します。

このサイクルはコードの変更なしに完結します。統計的有意差が出た段階でフラグをデフォルト値として確定させ、A/B分岐のコードを削除するクリーンアップを行います。

3.4 AppConfig Agentによる段階的ロールアウト

AppConfig Agentのバージョン2.0.136060以降では、セグメントや個別ユーザー単位での段階的ロールアウトが利用できます。これにより、特定のユーザーグループだけに新機能を試験提供し、問題がなければ対象範囲を拡大するプログレッシブデリバリーを実現できます。

セグメントによる段階展開

AppConfig Agentのセグメント機能では、ユーザーIDやカスタムコンテキスト属性をもとにルーティングルールを定義します。

# AppConfig Agentの設定例
rollout:
  - segment: "internal-users"
 percentage: 100
  - segment: "beta-testers"
 percentage: 100
  - segment: "all-users"
 percentage: 10

上記の設定では、まず社内ユーザーと先行登録ユーザーに100%展開し、一般ユーザーには10%のみ配信します。問題がなければ一般ユーザーへのパーセンテージを段階的に引き上げます。

一貫性保証: 同一ユーザーへの継続配信

AppConfig Agentの段階的ロールアウトで特に重要な特性として、「一度フラグを受け取ったユーザーは、そのバージョンを継続して受け取る」という一貫性保証があります。

これはユーザー体験の観点から重要です。例えば、新しいUIを10%のユーザーに展開した場合、その10%に含まれたユーザーはページ遷移やセッション再開後も同じ新UIを受け取り続けます。ランダムに表示が切り替わるとユーザーが混乱するため、この一貫性保証は本番ユースで不可欠です。

ユーザーIDをX-Context-IdヘッダーまたはコンテキストキーとしてAgentに渡すことで、同一ユーザーへの一貫したバリアント割り当てが実現します。

3.5 バージョンラベルとフラグのライフサイクル

バージョンラベル

AppConfigの構成バージョンには任意のラベルを付与できます。ラベルを活用すると、特定バージョンをstablebetaとして明示的にタグ付けし、環境ごとに異なるバージョンを参照させる運用が実現します。

フィーチャーフラグ v1.0 → label: stable → Production環境
フィーチャーフラグ v1.1 → label: beta→ Staging環境

デプロイ時にラベルを指定するCLIの例を以下に示します。

aws appconfig create-deployment \
  --application-id MyApp \
  --environment-id Production \
  --configuration-profile-id FeatureFlags \
  --configuration-version-label stable \
  --deployment-strategy-id AllAtOnce

ラベルを使用したデプロイにより、「どのバージョンが今どの環境で稼働しているか」の可視化と管理が容易になります。

フラグのライフサイクルとフラグ負債の回避

フィーチャーフラグは短命であるべきです。リリース完了後も残り続けるフラグは「フラグ負債」として蓄積し、コードの可読性低下やバグの温床となります。フラグのライフサイクル管理の指針を以下に示します。

フェーズ対応
作成フラグ名・目的・削除予定日をドキュメントに記録
テスト中ステージング環境でONにして動作検証
段階展開カナリアまたはセグメントでONを拡大
全面ON全環境でONに切り替え後、コードの分岐を削除
削除AppConfigからフラグを削除し、コードのフラグ参照も除去

フラグを短命に保つには、スプリントの計画段階でフラグの削除タスクをバックログに積んでおくことを推奨します。継続的なフラグ棚卸しにより、フラグ負債の蓄積を防止できます。

3.6 アプリ側でのフラグ評価

シンプルなフラグ評価

最もシンプルなON/OFFフラグの評価パターンを以下に示します。

def is_feature_enabled(flags: dict, feature_name: str) -> bool:
 flag = flags.get(feature_name, {})
 return flag.get('enabled', False)

# 使用例
if is_feature_enabled(flags, 'newCheckoutFlow'):
 return new_checkout_handler(request)
else:
 return legacy_checkout_handler(request)

このパターンではLambdaハンドラーの先頭でAppConfigからフラグを取得し、後続の処理を分岐させます。

属性値の取得とデフォルト値

属性付きフラグから値を取得する際は、デフォルト値を必ず設定してください。AppConfigへの接続が一時的に失敗した場合でも、アプリが既知のデフォルト動作にフォールバックするためです。

def get_flag_attribute(flags: dict, feature_name: str, attr_name: str, default):
 flag = flags.get(feature_name, {})
 if not flag.get('enabled', False):
  return default
 attrs = flag.get('attributes', {})
 return attrs.get(attr_name, {}).get('value', default)

# 使用例
max_items = get_flag_attribute(flags, 'recommendationEngine', 'maxRecommendations', 5)

フラグ評価ロジックをユーティリティ関数にまとめることで、変更時の修正箇所を最小限に抑えられます。アプリ全体でフラグ取得と評価のパターンを統一しておくことが、保守性の向上につながります。

フィーチャーフラグの機能

  • フラグ定義 — enabled ON/OFF。属性付きフラグ(数値/文字列/真偽・制約付き)で挙動を制御
  • マルチバリアントフラグ — 条件(ユーザー属性等)で異なる値を返す(A/Bテスト/段階リリース)
  • AppConfig Agent — セグメント/個別ユーザー単位の段階的ロールアウト(同一ユーザーは同一バージョン継続)
  • ★短命フラグの掃除でフラグ負債を回避。コード再デプロイ不要で機能ON/OFF

4. 動的設定 — フリーフォーム構成と検証

fig04: AppConfig動的設定の検証フロー(フリーフォーム構成のデプロイ前にJSON SchemaバリデーターとカスタムLambdaバリデーターで検証し、不正な設定の本番配信を防ぐ構成)
fig04: 動的設定の検証 — JSON Schema/Lambda validatorによる事前検証

動的設定とは — 再デプロイなしに変わる設定層

フィーチャーフラグが機能のON/OFFを制御するのに対し、フリーフォーム構成(動的設定)は任意の形式でアプリケーションの挙動パラメーターを管理する仕組みです。レート制限値、タイムアウト、外部エンドポイントURL、IPアドレスの許可リスト、サービス間の接続設定など、コードに埋め込みたくないがデプロイなしに変更したい値が対象になります。

従来の設定管理では「コードを変更してビルドし直す」か「環境変数を更新してアプリを再起動する」しかありませんでした。どちらもリリースサイクルに縛られるため、緊急のレート制限変更や外部エンドポイントの切替に時間がかかります。AppConfigのフリーフォーム構成は、この問題をランタイム設定配信で解決します。

フリーフォーム構成が扱えるデータ形式は以下のとおりです。

  • JSON — 構造化された設定オブジェクト。型や階層を持てるため最もよく使われます
  • YAML — 可読性が高く、複雑なリスト/マップ構成に向いています
  • プレーンテキスト — シンプルな文字列値や改行区切りリストなど

どの形式でも、AppConfigのバリデーター機能と組み合わせることで配信前の品質チェックが可能です。


フリーフォーム構成の実用例

実際にフリーフォーム構成で管理する値の具体例を示します。

{
  "rate_limits": {
 "api_calls_per_second": 100,
 "burst_limit": 200
  },
  "timeouts": {
 "connection_ms": 3000,
 "read_ms": 10000
  },
  "allowed_ip_ranges": [
 "203.0.113.0/24",
 "198.51.100.0/24"
  ],
  "external_endpoints": {
 "payment_gateway": "https://pay.example.com/api/v2",
 "notification_service": "https://notify.example.com"
  },
  "feature_thresholds": {
 "max_retry_count": 3,
 "cache_ttl_seconds": 300
  }
}

この設定をコード変更なしに更新できれば、レート制限の緊急引き下げや外部サービスの切替先変更に即応できます。アプリ側はポーリング(または起動時取得)で最新値を受け取り、次回処理から新しい設定を使い始めます。


検証(バリデーター)— 不正設定の本番配信を防ぐセーフガード

フリーフォーム構成の最大のリスクは「意図しない値が本番に配信されてしまうこと」です。タイムアウトに負の値、レート制限に文字列、必須フィールドの欠落――こうした不正設定が本番に流れると、アプリが誤動作するまで原因を特定しづらくなります。

AppConfigはこのリスクに対し、デプロイ前の自動検証を提供しています。構成プロファイルにバリデーターを設定しておくと、設定の新しいバージョンをデプロイしようとした時点で検証が走り、不正なら配信自体がブロックされます。

バリデーターには2種類あります。


① JSON Schemaバリデーター

JSON Schema(Draft 4/6/7に対応)を使って、設定の構造と値の型、必須フィールド、値の範囲を宣言的に定義します。スキーマに反する設定はデプロイを拒否されるため、型ミスや必須フィールドの欠落を自動で弾けます。

先ほどの例に対応するJSON Schemaを示します。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["rate_limits", "timeouts"],
  "properties": {
 "rate_limits": {
"type": "object",
"required": ["api_calls_per_second", "burst_limit"],
"properties": {
  "api_calls_per_second": {
 "type": "integer",
 "minimum": 1,
 "maximum": 10000
  },
  "burst_limit": {
 "type": "integer",
 "minimum": 1
  }
}
 },
 "timeouts": {
"type": "object",
"required": ["connection_ms", "read_ms"],
"properties": {
  "connection_ms": {
 "type": "integer",
 "minimum": 100,
 "maximum": 60000
  },
  "read_ms": {
 "type": "integer",
 "minimum": 100
  }
}
 },
 "allowed_ip_ranges": {
"type": "array",
"items": { "type": "string" }
 }
  }
}

このスキーマをコンソール上またはAPI経由で構成プロファイルに登録しておくと、設定が保存されるたびに自動チェックが走ります。api_calls_per_second"hundred"という文字列を入れようとした場合、スキーマ違反でデプロイが失敗します。

JSON Schemaバリデーターが得意なこと:

  • 型の強制(integer/string/boolean/array/objectの混在防止)
  • 必須フィールドの欠落検出
  • 数値の範囲チェック(minimum/maximum)
  • 文字列パターンの検証(pattern/format)
  • 配列要素の型統一

② カスタムLambdaバリデーター

JSON Schemaで表現できないビジネスロジック検証には、Lambda関数をバリデーターとして設定します。AppConfigは設定のデプロイ前にそのLambdaを呼び出し、Lambdaが検証成功を返せば配信を続行し、失敗を返せばブロックします。

Lambdaバリデーターが活きるシナリオ:

  • フィールド間の依存関係チェックburst_limitapi_calls_per_secondの2倍以上でなければならない、など
  • 外部システムとの整合性 — 設定に含まれるエンドポイントURLが実際に応答するか疎通確認
  • 許可リストのフォーマット検証 — IPアドレスが正しいCIDR形式か、重複していないか
  • 組み合わせ禁止チェック — 特定の設定値Aと設定値Bを同時に有効化すると問題が起きる場合

Lambda関数のシグネチャは以下のようになります。

import json
import base64

def lambda_handler(event, context):
 # AppConfigはconfigurationをBase64エンコードして渡す
 config_str = base64.b64decode(event['content']).decode('utf-8')
 config = json.loads(config_str)

 errors = []

 # burst_limitはapi_calls_per_secondの2倍以上であること
 rate_limits = config.get('rate_limits', {})
 calls_per_sec = rate_limits.get('api_calls_per_second', 0)
 burst = rate_limits.get('burst_limit', 0)
 if burst < calls_per_sec * 2:
  errors.append(
f"burst_limitはapi_calls_per_secondの2倍以上が必要です"
f"(現在: burst={burst}, 最小値={calls_per_sec * 2})"
  )

 if errors:
  raise Exception('\n'.join(errors))

 return {
  'statusCode': 200,
  'body': json.dumps({'message': '検証OK'})
 }

AppConfigはLambdaの実行結果を確認し、例外(エラー)が発生した場合はデプロイを中止します。Lambdaの実行ログはCloudWatch Logsに記録されるため、検証失敗の原因を追いやすい点も利点です。


バリデーターの組み合わせ

JSON SchemaバリデーターとLambdaバリデーターは同時に設定できます。実際の運用では、まずJSON Schemaで構造的な正しさを素早くチェックし、スキーマをパスした設定だけをLambdaで高度なビジネスロジック検証にかけるという二段階構成が効果的です。

検証種別得意な用途実行タイミング
JSON Schemaバリデーター型・必須フィールド・値範囲デプロイリクエスト時
Lambdaバリデータービジネスロジック・外部整合性デプロイリクエスト時

どちらの検証も失敗した場合、設定は本番環境に配信されません。エラーメッセージがコンソールとAPIレスポンスに返されるため、何が不正だったかをオペレーターがすぐに確認できます。


バージョン管理とロールバック

AppConfigはフリーフォーム構成の変更をバージョンとして管理します。設定を新しく保存するたびに新しいバージョン番号が付与され、古いバージョンは保持されます(デフォルトで最新1000バージョンまで保持)。

バージョン管理のメリット:

  • 変更履歴を辿ることで「いつ・何を変えたか」を追跡できます
  • 問題が発生した際に前のバージョンへ即座にロールバックできます
  • 複数の環境(本番/ステージング)に異なるバージョンを配信してテストできます

コンソール上のロールバック操作は「前のバージョンを再デプロイ」するだけです。デプロイ戦略が設定されていれば段階的にロールバック版が配信され、即時デプロイを選べば全ホストに一括適用されます。

バージョンラベルを使うと特定バージョンに名前を付けて管理しやすくなります。たとえばstable-2026-06のようなラベルを付けておくと、ロールバック先を名前で指定できます。


保管先の選択

AppConfigのフリーフォーム構成は、設定データをどこに保管するかを選択できます。

保管先特徴向いている用途
AppConfigホスト型AppConfig側で完結。コンソール/APIで直接編集シンプルな設定管理・バリデーター一体運用
Amazon S3大容量・バージョニング・既存S3運用との統合大きなJSONファイルや既存S3ワークフロー
SSM Parameter Storeパラメーターストアとの共用・既存参照コード再利用既にSSM連携済みのシステム
SSM Documentドキュメント形式での設定管理Systems Manager中心の運用環境

ほとんどの新規プロジェクトではAppConfigホスト型が最もシンプルな選択です。S3に設定ファイルを置いてCI/CDパイプラインで更新する既存フローがある場合は、S3保管型のままAppConfigのデプロイ戦略と検証だけを追加するアプローチも取れます。


設定の外部化 — アンチパターンからの脱却

動的設定を導入する前、多くのチームが陥りやすいアンチパターンを整理します。

アンチパターン1: ハードコード

設定値をソースコード内に直接書いてしまうケースです。MAX_RATE = 100のような定数は変更のたびにコードのビルドとデプロイが必要になります。本番で緊急にレート制限を下げたい場合でもリリースフローを通さなければならず、対応が遅れます。

アンチパターン2: 環境変数依存

環境変数はハードコードよりは柔軟ですが、変更するにはアプリを再起動(またはタスクの再デプロイ)が必要です。ECSタスクやLambda関数の環境変数を変えても、コールドスタートするまで反映されません。環境変数はプレーンテキストのみで構造化された設定を扱いにくく、バリデーション機能もありません。

脱却のポイント

AppConfigのフリーフォーム構成に移行すると、設定値の変更がコードのライフサイクルから切り離されます。

  • レート制限の緊急変更 → コンソール操作のみで即日反映
  • 外部エンドポイントの切替 → デプロイなしで変更し、ロールバックも容易
  • 複数環境での設定差分管理 → 環境ごとに独立したバージョンを配信

検証なしデプロイの危険性

「動的設定は再デプロイ不要だから手軽に変更できる」という認識は正しいですが、バリデーターなしで運用するのは危険です。

検証なしデプロイで起きやすい事故:

  • タイムアウト値を誤って0に設定 → 全リクエストが即座にタイムアウトし障害発生
  • 必須の外部エンドポイントを空文字に設定 → 接続先がなく機能停止
  • 数値フィールドに文字列を混入 → アプリ側の型変換で例外が多発
  • 許可リストの形式ミス → セキュリティフィルターが意図しない動作

これらはバリデーターを設定しておけばデプロイ前にブロックできます。「設定変更だけだから大丈夫」という油断をなくすため、フリーフォーム構成には必ずJSON Schemaバリデーターを設定することを運用ルールにしてください。ビジネスロジックが複雑な場合はLambdaバリデーターを追加します。


アプリからの取得と動的設定の関係

フリーフォーム構成の取得方法(Lambda extension、AppConfig Agent、SDK直接呼び出し)の詳細は後述の統合・運用セクションで扱います。ここでは基本的な流れを整理します。

アプリケーションが設定を取得するタイミングは2種類あります。

  1. 起動時取得 — アプリ起動時に一度だけ設定を取得してキャッシュします。シンプルですが新しい設定への追従は再起動が必要です
  2. 定期ポーリング — 数十秒〜数分間隔で設定の更新有無を確認します。更新があれば取得し直すことでランタイムへの設定変更が反映されます

AppConfigのLambda extensionやAgentはローカルキャッシュを持ち、設定が変わっていない場合はAPIを呼び出さずにキャッシュを返します。コストとレイテンシを最小化できる点が実用上の大きなメリットです。

フリーフォーム構成はアプリのポーリング間隔とバリデーターの組み合わせにより、「安全な変更だけを迅速に届ける」仕組みとして機能します。設定変更が本番の障害に直結しないよう、検証・バージョン管理・段階配信の三つを組み合わせて運用するのが正しいアプローチです。

動的設定の要点

  • フリーフォーム構成 — JSON/YAML/テキスト設定(レート制限/タイムアウト/許可リスト等)を再デプロイなしに変更
  • ★検証=JSON Schemaバリデーター(構造/型/範囲)+カスタムLambdaバリデーター(ビジネスロジック)
  • 不正設定の本番配信を防ぐセーフガード。バージョン管理とロールバック
  • ハードコード/環境変数の再デプロイ依存から脱却し設定を外部化

5. デプロイ戦略&セーフガード

fig05: AppConfigデプロイ戦略と自動ロールバック(リニア/カナリア/即時のデプロイ戦略でステップ配信し、デプロイ中にCloudWatchアラームが発火したら自動で前バージョンへロールバックするMermaidフロー)
fig05: デプロイ戦略&自動ロールバック — 段階配信とCloudWatchアラーム連動(Mermaid)

デプロイ戦略の役割とblast radius制限

AWS AppConfigのデプロイ戦略は、設定変更やフィーチャーフラグを各ホスト(アプリケーションインスタンス)へ配信する方法を定義し、障害発生時の影響範囲(blast radius)を最小限に抑える仕組みです。設定変更はコードのデプロイと異なり、アプリケーション全体へ即座に影響します。適切な戦略を選択することで、段階的に配信しながらアラームを監視し、問題を早期に検知して自動ロールバックする安全な設定変更プロセスを実現できます。

デプロイ戦略は「デプロイ戦略ID」として管理され、デプロイ時にEnvironmentへ適用します。AWSが提供する標準テンプレートを使うか、要件に合わせたカスタム戦略を作成できます。

3種のデプロイ戦略

AppConfigは3つの基本配信方式を提供しています。用途と安全要件に応じて選択します。

即時配信(AllAtOnce)

全ホストへ設定変更を一括配信します。配信は最速で完了時間が短い反面、問題が発生した場合は全インスタンスが同時に影響を受けます。blast radiusが最大となるため、本番環境では事前に十分検証した設定か、緊急のキルスイッチ操作に限定することを推奨します。

  • 配信速度: 最速
  • blast radius: 最大(全インスタンス同時影響)
  • 主なユースケース: 開発・ステージング環境、緊急停止操作、検証済みのマイナー設定変更

段階配信(リニア)

設定変更をステップごとに均等な割合で段階的に配信します。たとえば成長率10%を指定すると、全ホストの10%→20%→30%→…→100%と10回のステップに分けて配信します。各ステップ間の待機時間は「デプロイ時間÷ステップ数」で決まります。問題が早い段階で発覚すれば、残りのホストへの影響を防ぐことができます。

  • 配信速度: 中程度(デプロイ時間で制御)
  • blast radius: ステップごとに段階的に増加
  • 主なユースケース: 設定変更の影響を均等に広げたい場合、定期的なパラメータ更新

指数配信(カナリア)

少数のホスト(カナリアグループ)へ最初に配信し、問題がなければ残り全体へ一括展開します。たとえばCanary10Percent20Minutesテンプレートでは、全体の10%へ配信して20分間監視した後、残り90%へ一括配信します。最初のカナリアグループでの動作を確認してから全体展開するため、blast radiusを最小化できます。

  • 配信速度: 初期は低く、後半は全体一括
  • blast radius: 初期は最小(カナリアグループのみ)
  • 主なユースケース: 本番環境での新設定展開、フィーチャーフラグの段階ロールアウト、A/Bテスト

デプロイ設定パラメータ

デプロイ戦略の動作を制御する4つのパラメータを設定します。

デプロイ時間(Deployment Duration)

設定変更の配信を完了するまでの総時間を分単位で指定します。たとえば60分を指定すると、60分をかけてステップ配信が進みます。0を指定すると即時配信となります。デプロイ時間が長いほど各ステップでの監視時間が増え、問題を早期に検知しやすくなります。

最終ベイク時間(Final Bake Time)

最後のステップで全ホストへ配信完了後、デプロイ成功とみなすまでの監視猶予時間です。この時間内にCloudWatchアラームがALARM状態にならなければデプロイ完了、問題があれば自動ロールバックが発動します。

本番環境では5〜30分程度のベイク時間を設けることを推奨します。ベイク時間を0にすると、配信完了直後に顕在化する問題を見逃すリスクが高まります。

成長率(Growth Factor)

各ステップで配信するホストの割合(%)です。リニア配信では均等な割合を指定します(例: 25%を指定すると4ステップで100%に到達)。カナリア配信では最初のカナリアグループへの配信割合を指定します(例: 10%)。

成長タイプ(Growth Type)

LINEAR(均等なステップ配信)またはEXPONENTIAL(指数的配信)を選択します。カナリア戦略ではEXPONENTIALを使用します。

CloudWatchアラーム自動ロールバック — 本番安全性の核心

AppConfigの最も重要な安全機能が、CloudWatchアラームとの連動による自動ロールバックです。デプロイ中(ステップ配信中)または最終ベイク時間中に、Environmentに紐付けたCloudWatchアラームがALARM状態へ遷移すると、AppConfigは自動的に前バージョンの設定へロールバックします。

設定手順

Environmentの作成または更新時に、監視するCloudWatchアラームをMonitorsとして紐付けます。

{
  "Name": "Production",
  "ApplicationId": "your-app-id",
  "Monitors": [
 {
"AlarmArn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm:AppErrorRate",
"AlarmRoleArn": "arn:aws:iam::123456789012:role/AppConfigMonitorRole"
 },
 {
"AlarmArn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm:AppLatencyP99",
"AlarmRoleArn": "arn:aws:iam::123456789012:role/AppConfigMonitorRole"
 }
  ]
}

AlarmRoleArnにはcloudwatch:DescribeAlarms権限を持つIAMロールを指定します。信頼ポリシーにはappconfig.amazonaws.comを信頼する設定が必要です。

アラーム設計例

設定変更の影響を適切に検知するために、以下のアラームを設定します。

アラーム監視対象閾値の目安評価期間
エラー率上昇アプリケーションの5xxエラー率>1%3分間で2回
レイテンシ増加P99レイテンシ>500ms5分間で3回
ビジネスKPI異常注文失敗数>10件/分2分間で1回
Lambda関数エラーエラー数カウント>5件1分間で1回

業務要件に合わせて閾値を調整します。閾値が厳しすぎると誤検知によるロールバックが頻発し、緩すぎると障害の検知が遅れます。実際のトラフィックパターンを分析してから設定することを推奨します。

自動ロールバックの動作

ロールバックが発動すると、AppConfigは進行中のデプロイを中断し、直前に正常動作していた設定バージョンへ自動復帰します。ロールバック後の状態はCloudWatchのデプロイイベントで確認できます。手動介入なしに本番事故を自動収束させるこのメカニズムが、段階配信と並んでAppConfigの安全性を支える核心です。

CloudWatchのアラーム作成やメトリクス設定の基本については、CloudWatch本番運用の記事を参照してください。

AppConfig提供デプロイ戦略テンプレート

AppConfigにはあらかじめ3つの標準テンプレートが用意されており、すぐに利用できます。

テンプレート名成長タイプデプロイ時間ベイク時間概要
AppConfig.AllAtOnceLINEAR0分0分全ホストへ即時配信
AppConfig.Linear50PercentEvery30SecondsLINEAR1分0分30秒ごとに50%ずつ配信(2ステップ)
AppConfig.Canary10Percent20MinutesEXPONENTIAL20分10分10%カナリア→20分後に残り90%配信

本番環境ではCanary10Percent20Minutesが推奨テンプレートです。最初の10%のホストへ配信して20分間ベイク、問題なければ残り90%へ展開、さらに10分間ベイクして完了します。この全工程でCloudWatchアラームが常時監視し、異常を検知すれば自動ロールバックが発動します。

カスタムデプロイ戦略の作成

標準テンプレートで要件を満たせない場合は、カスタム戦略を作成します。AWS CLIでは以下のように実行します。

aws appconfig create-deployment-strategy \
  --name "MyProductionStrategy" \
  --deployment-duration-in-minutes 60 \
  --final-bake-time-in-minutes 30 \
  --growth-factor 20 \
  --growth-type LINEAR \
  --replicate-to "NONE"

用途別のパラメータ設計指針:

  • リリース頻度が高い設定変更: デプロイ時間30分・ベイク時間5分・成長率25%(4ステップ)
  • 本番クリティカルな設定変更: デプロイ時間60分・ベイク時間30分・カナリア10%
  • 緊急キルスイッチ用途: デプロイ時間0・ベイク時間0(手動監視を必ず実施)

--replicate-toオプションはNONE(複製なし)またはSSM_DOCUMENT(Systems Manager Documentsへ複製)を選択します。通常はNONEを指定します。

デプロイ戦略選択の指針

本番環境で適切な戦略を選ぶための判断基準を整理します。

シーン推奨戦略CloudWatchアラーム
本番クリティカルな設定変更Canary10Percent20Minutes必須(エラー率+レイテンシ)
定期的なパラメータ更新(影響軽微)Linear50PercentEvery30Seconds推奨
開発・ステージング環境AllAtOnceオプション
緊急キルスイッチ操作AllAtOnce手動監視で代替

段階配信とCloudWatchアラーム自動ロールバックを組み合わせることで、AppConfigは設定変更を安全に本番環境へ届ける基盤を提供します。設定変更の影響範囲と許容リスクを考慮して戦略を選択し、アラームを確実に設定することが、安全なフィーチャーフラグ・動的設定運用の核心です。

デプロイ戦略とセーフガード

  • デプロイ戦略 — 即時/リニア(ステップ%均等)/カナリア(指数的・少数→拡大)でblast radiusを限定
  • デプロイ設定 — デプロイ時間/bake time(監視猶予)/ステップ%/成長タイプ
  • ★CloudWatchアラーム自動ロールバック — デプロイ中にアラームがALARMになると前バージョンへ自動復帰
  • 提供テンプレート(AllAtOnce/Linear50/Canary10Percent20Minutes等)。段階配信+自動ロールバックが安全性の核心

6. 統合・運用・コスト

AppConfigから設定を取得する方法は3種あります。①Lambda extension、②AppConfig Agent、③SDK直接取得です。取得方法の選択がコスト効率とレイテンシに直結するため、実行環境に合わせた適切な選択が重要です。

取得方法① AppConfig Lambda extension(推奨)

Lambda関数からAppConfigの設定を取得する場合、Lambda extensionの利用が推奨です。Lambda extensionはLambda関数のサイドカーとして動作するプロセスであり、設定のローカルキャッシュと定期ポーリングを担います。

動作の仕組み

Lambda extensionはLambda実行環境内のバックグラウンドプロセスとして起動し、設定をローカルHTTPサーバー(http://localhost:2772)でキャッシュします。関数コードは、AppConfigに直接APIコールするのではなく、このlocalhost経由でキャッシュされた設定を取得します。

import json
import http.client

def get_config(app, env, profile):
 conn = http.client.HTTPConnection("localhost", 2772)
 conn.request("GET", f"/applications/{app}/environments/{env}/configurations/{profile}")
 res = conn.getresponse()
 return json.loads(res.read().decode("utf-8"))

ポーリング間隔とキャッシュの動作

extensionがAppConfigへポーリングする間隔は、環境変数AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDSで制御します。デフォルトは45秒です。ポーリング時に設定が変更されていれば、extensionはキャッシュを更新します。変更がなければ、AppConfigはHTTP 304 Not Modifiedを返し、設定の転送コストが発生しません。

関数コードがlocalhost経由で設定を参照するたびにAppConfigへのAPIコールが発生するわけではありません。キャッシュが有効な間はlocalhost内部で完結するため、関数コードからの取得レイテンシは非常に低く抑えられます。

Lambda extensionの追加方法

Lambda extensionはLambdaレイヤーとして追加します。AWSリージョンごとに提供されており、AWS公式ドキュメントでリージョン別ARNを確認します。Terraformではlayers引数にARNを追加するだけで利用可能です。

resource "aws_lambda_function" "example" {
  function_name = "my-function"
  layers = ["arn:aws:lambda:ap-northeast-1:XXXX:layer:AWS-AppConfig-Extension:XX"]
  environment {
 variables = {
AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS = "45"
 }
  }
}

取得方法② AppConfig Agent(ECS/EKS/EC2向け)

Lambda以外の環境(ECS/EKS/EC2)では、AppConfig Agentをサイドカーコンテナまたはデーモンプロセスとして使います。Lambda extensionと同様に、ローカルHTTPエンドポイント経由でアプリケーションコンテナが設定を取得します。

ECSでのサイドカー構成

ECSタスク定義にAppConfig Agentコンテナを追加します。AppConfig AgentはAWS提供のコンテナイメージとして利用でき、アプリコンテナはlocalhost経由で設定を取得します。

{
  "name": "appconfig-agent",
  "image": "public.ecr.aws/aws-appconfig/aws-appconfig-agent:latest",
  "environment": [
 {"name": "SERVICE_REGION", "value": "ap-northeast-1"},
 {"name": "PREFETCH_LIST", "value": "MyApp:production:FeatureFlags"}
  ]
}

アプリケーションコンテナはLambda extensionと同じURLパターン(http://localhost:2772/applications/...)で設定を取得します。PREFETCH_LISTで起動時にプリフェッチする設定を指定すると、コールドスタート時の初回取得レイテンシを抑えられます。

AppConfig Agentの主な設定パラメータ

パラメータ説明デフォルト
POLL_INTERVALポーリング間隔(秒)45
MAX_CONNECTIONSAppConfigへの最大接続数3
PREFETCH_LISTプリフェッチする設定リストなし
LOG_LEVELログレベル(DEBUG/INFO/WARN/ERROR)INFO

取得方法③ SDK直接取得

AppConfig AgentやLambda extensionを使わず、AWS SDKで直接APIを呼ぶ方法です。柔軟性は高いですが、ローカルキャッシュを自前で実装しないとAPI呼出頻度が上がり、コスト増につながります。SDK直接取得を使う場合は、必ずアプリケーション側でキャッシュを実装し、変更がない場合のAPI呼出を抑制します。

extensionとAgentはこのキャッシュ最適化を内部で自動的に行うため、特別な理由がない限りSDK直接取得より推奨されます。

コスト構造

AppConfigの料金は主に2つの要素で構成されます。

取得リクエスト課金

GetLatestConfiguration APIの呼出1,000件あたりで課金されます。Lambda extensionやAgentがポーリングするごとにカウントされますが、HTTP 304(変更なし)のレスポンス時も課金対象となります。

構成受信課金

設定が変更されて実際にデータが転送された際(HTTP 200レスポンス)に、受信した設定データのサイズに応じて課金されます。設定が変更されない場合は、取得リクエスト料金のみが発生します。

コスト最適化のポイント

ポーリング間隔が短いほどAPIコールが増えます。たとえばポーリング間隔10秒と45秒では、コール数に約4倍の差が出ます。設定変更の即時性要件とコストのバランスを取りながら、ポーリング間隔を設計します。変更頻度が低い設定はポーリング間隔を長めに設定できます。Lambda extensionやAgentのローカルキャッシュを活用することで、アプリケーションコードからの参照頻度に関わらずAPIコールを抑制できます。

フィーチャーフラグの変更が即時に近いタイミングで反映される必要があるユースケース(キルスイッチ等)では短めのポーリング間隔を設定し、変更頻度が低い動的設定(レート制限値等)は長めのポーリング間隔を設定するという、プロファイルごとの使い分けも有効です。

CloudWatchメトリクスによる監視

AppConfigはデプロイ状態と設定取得の状況をCloudWatchメトリクスとして発行します。

デプロイ関連メトリクス

デプロイの成否(DeploymentSuccess / DeploymentFailed)とロールバックの成否(RollbackSuccess / RollbackFailed)をCloudWatchアラームで監視します。デプロイの失敗やロールバックが発生した際、即座に通知を受け取ることで設定配信の問題を早期に検知できます。

取得エラーの監視

Lambda extensionやAgentが設定の取得に失敗した際、最後に成功したキャッシュを返し続けます(stale cache)。取得エラーが継続する場合はCloudWatchアラームで検知し、AppConfigへの疎通とIAM権限を確認します。

AppConfigのデプロイイベントはEventBridgeへも発行され、デプロイ開始・完了・ロールバックをトリガーとした自動化処理を実装できます。たとえば、デプロイ完了後にSlack通知を送る、ロールバック時にインシデントチケットを自動作成するといった運用自動化が可能です。

マルチアカウント / マルチリージョン展開

複数のAWSアカウントや複数リージョンにサービスを展開する場合、AppConfigのリソースはリージョン単位で管理します。各リージョン・各アカウントに同じApplicationとEnvironmentを作成し、Terraformで一元管理するパターンが一般的です。

マルチリージョン展開での設定変更は、リージョンごとにデプロイを実行します。CI/CDパイプラインでリージョンをパラメータ化してシーケンシャルにデプロイし、各リージョンのCloudWatchアラームが安定したことを確認してから次のリージョンへ進めるパターンを推奨します。これにより、設定変更による障害が全リージョンへ同時に波及するリスクを排除できます。

マルチアカウント環境では、AWS OrganizationsとAWS Configを組み合わせてAppConfigの利用状況を一元的に把握する運用も検討できます。

IAM権限の最小化

AppConfigを利用するアプリケーションには最小権限のIAMポリシーを付与します。

{
  "Version": "2012-10-17",
  "Statement": [
 {
"Effect": "Allow",
"Action": [
  "appconfig:StartConfigurationSession",
  "appconfig:GetLatestConfiguration"
],
"Resource": "arn:aws:appconfig:ap-northeast-1:ACCOUNT_ID:application/APP_ID/environment/ENV_ID/configuration/PROFILE_ID"
 }
  ]
}

リソースARNをConfiguration Profile単位まで絞ることで、アプリケーションが参照できる設定を必要最小限に限定できます。AppConfigの管理操作(デプロイ実行、設定更新)はCI/CDパイプラインやオペレーターのIAMロールに分離し、アプリケーション実行ロールには読み取り専用の権限のみを付与します。

AppConfigのAPIアクションはappconfig:プレフィックスを持ち、Systems Managerのポリシー(ssm:*)とは独立して管理できます。Systems Manager Parameter Storeを設定のバッキングストアとして使う場合は、ssm:GetParameterも必要になります。SSM Parameter Storeを使う場合は、パラメータのARNをリソース指定に加えて最小権限を維持します。

統合・運用・コストの要点

  • 取得方法 — Lambda extension(低レイテンシ・推奨)/AppConfig Agent(ECS/EKS/EC2)/SDK直接(GetLatestConfiguration)
  • ★コスト=取得リクエスト+構成受信課金。ローカルキャッシュ(extension/Agent)でAPI呼出削減
  • 監視 — CloudWatchメトリクス(デプロイ状態/取得エラー)・デプロイイベント
  • ポーリング間隔とキャッシュの設計。マルチアカウント/リージョン展開

7. 実戦統合パターン — フィーチャーフラグ運用と段階リリース

fig06: AppConfig実戦統合パターン(フィーチャーフラグによる段階リリース、CI/CDパイプラインからの構成デプロイ、A/Bテスト、キルスイッチ運用を、既存CI/CD・Lambdaと連携させる選定フローのMermaid図)
fig06: 実戦統合パターン — 段階リリース/A-Bテスト/キルスイッチ運用(Mermaid)

フィーチャーフラグと動的設定を最大限に活用するには、既存のCI/CDパイプラインや運用フローと統合した実戦的なパターンが重要です。本節では、段階リリース、キルスイッチ、A/Bテスト、運用フラグ、CI/CD連携、フラグ運用のガバナンスを解説します。

7.1 段階リリース — コードデプロイと設定切替の分離

フィーチャーフラグを使った段階リリースの核心は、コードのデプロイと機能の有効化を分離することです。新機能のコードは先にデプロイ済みの状態にして、本番でフラグをONにすることで機能を有効化します。

段階リリースのフロー

1. 新機能コードをフラグOFFでデプロイ
↓
2. 社内ユーザーに対してフラグON(内部テスト)
↓
3. カナリアデプロイで全ユーザーの10%にフラグON
↓
4. CloudWatchでエラー率/レイテンシを監視(bake time中)
↓
5. 問題なければ50%→100%と段階的に拡大
↓
6. 全面展開後、フラグを削除(コードのフラグ分岐も除去)

このフローにより、問題が発生した場合はフラグをOFFにするだけで即座に機能を無効化できます。コードのロールバック(新しいコードの再デプロイ)は不要なため、障害時の平均復旧時間(MTTR)を大幅に短縮できます。

コードデプロイとフラグ切替の比較

操作所要時間リスク
コードロールバック(再デプロイ)数分〜十数分ビルド/テスト失敗のリスク
フラグOFFによる機能無効化数秒〜数十秒ほぼなし
フラグのカナリアデプロイ設定した展開時間段階的に限定

コードデプロイのリスクと速度を考えると、フィーチャーフラグによる段階リリースは大規模システムの本番運用で標準的なアプローチとなっています。

7.2 キルスイッチ — 再デプロイ不要の緊急停止

キルスイッチは、障害や予期せぬ問題が発生した際に特定の機能を即座に無効化する仕組みです。新機能のテスト中に深刻なバグが見つかった場合や、データベース負荷が急増した場合でも、フラグをOFFにするだけで対応できます。

キルスイッチの実装パターン

専用のキルスイッチフラグを設けて、問題のある機能と1対1で対応させます。

{
  "newPaymentGateway": {
 "enabled": true
  },
  "newSearchIndexer": {
 "enabled": true
  },
  "heavyAnalyticsJob": {
 "enabled": false
  }
}

インシデント対応時の手順を示します。

# 新しい構成バージョンを作成(フラグをOFFに変更)
aws appconfig create-hosted-configuration-version \
  --application-id MyApp \
  --configuration-profile-id KillSwitches \
  --content '{"newPaymentGateway": {"enabled": false}}' \
  --content-type application/json

# 即時デプロイ(AllAtOnce戦略)
aws appconfig start-deployment \
  --application-id MyApp \
  --environment-id Production \
  --deployment-strategy-id AllAtOnce \
  --configuration-profile-id KillSwitches \
  --configuration-version latest

このコマンドを実行すると、AppConfig Lambda extensionを使用しているLambda関数は次回のポーリング時にフラグの変更を取得します。より迅速な反映が必要な場合は、Lambda extensionのポーリング間隔を短縮するか、SDKを用いた直接取得を実装します。

インシデント対応フローへの統合

実際の本番運用では、インシデント対応ランブックにキルスイッチ手順を組み込みます。CloudWatchアラームが発火した際のアラートに「AppConfigコンソールURL」を記載しておくと、オンコール担当者が迷わず操作できます。

IAM権限として、オンコール担当者がappconfig:CreateHostedConfigurationVersionappconfig:StartDeploymentを実行できるポリシーを付与します。最小権限の原則に基づき、キルスイッチ用のApplicationと構成プロファイルに対してのみ権限を絞り込みます。

7.3 A/Bテスト — マルチバリアントフラグによるセグメント制御

A/BテストはAppConfigのマルチバリアントフラグとAppConfig Agentのセグメント機能を組み合わせて実現します。インフラと設定管理が一元化できるため、専用のA/Bテストツールを別途導入せずに実装可能です。

A/Bテストの設定例

新しいトップページデザインをテストするケースを示します。

{
  "topPageLayout": {
 "enabled": true,
 "attributes": {
"variant": {
  "constraints": {
 "type": "string",
 "enum": ["control", "treatment"]
  },
  "value": "control"
}
 }
  }
}

AppConfig Agentのセグメント設定で、ユーザーIDのハッシュ値をもとに全ユーザーを2グループに分割し、それぞれ異なるバリアントを受け取るように設定します。一度バリアントを受け取ったユーザーはセッションをまたいでも同一バリアントを受け取り続けるため、実験の一貫性が保たれます。

メトリクス収集と判定

A/Bテストの効果測定には、CloudWatch Metricsへのカスタムメトリクス送信を組み合わせます。アプリケーションのコード内でどのバリアントを受け取ったかをログに記録し、CloudWatch Logs Insightsでセグメント別のコンバージョン率やエラー率を集計します。

import boto3

cloudwatch = boto3.client('cloudwatch')

def track_conversion(variant: str, converted: bool):
 cloudwatch.put_metric_data(
  Namespace='AppABTest',
  MetricData=[{
'MetricName': 'Conversion',
'Dimensions': [{'Name': 'Variant', 'Value': variant}],
'Value': 1 if converted else 0,
'Unit': 'Count'
  }]
 )

統計的有意差が確認できた段階で、勝者バリアントを全ユーザーに展開します。その後、フラグ分岐のコードをクリーンアップしてフラグを削除します。

7.4 運用フラグ — メンテナンスモード・レート制限・サーキットブレーカー

フィーチャーフラグと動的設定は、新機能の段階リリースだけでなく、既存システムの運用制御にも活用できます。

メンテナンスモード

計画メンテナンス中にユーザーへのサービス提供を一時停止するためのフラグを設けます。

{
  "maintenanceMode": {
 "enabled": false,
 "attributes": {
"message": {
  "constraints": { "type": "string" },
  "value": "現在メンテナンス中です。しばらくお待ちください。"
},
"allowedRoles": {
  "constraints": { "type": "string" },
  "value": "admin,engineer"
}
 }
  }
}

maintenanceMode.enabledをONにすると、アプリがメンテナンス画面を表示します。allowedRoles属性を使って管理者と開発者は通常どおりアクセスできるように制御します。フラグをOFFに戻すだけでメンテナンスを終了できます。

動的レート制限

外部APIへのリクエスト数や内部処理の並列度をフリーフォーム構成で動的に制御します。

{
  "rateLimits": {
 "externalApiCallsPerMinute": 1000,
 "maxConcurrentJobs": 50,
 "batchSize": 100
  }
}

トラフィックスパイクや外部APIのリクエスト制限変更に対応するため、これらの値をコードに埋め込まずAppConfigで管理します。負荷状況に応じてコンソールから即座に変更可能です。

サーキットブレーカー

特定のサービスや外部依存への呼び出しを動的に遮断するサーキットブレーカーパターンをAppConfigで実装します。

{
  "circuitBreakers": {
 "externalPaymentService": {
"enabled": true,
"timeout_ms": 3000
 },
 "legacyInventoryService": {
"enabled": false,
"fallback": "cached"
 }
  }
}

enabled: falseに設定したサービスへの呼び出しをアプリが自動的にスキップし、フォールバック処理に切り替えます。インシデント時のサービス分離を再デプロイなしで実現できます。

7.5 CI/CDパイプラインとの連携

AppConfigの構成デプロイをCI/CDパイプラインに組み込むことで、コードのリリースと設定の変更を一貫したプロセスで管理できます。

CodePipelineとの統合

AWS CodePipelineにAppConfigデプロイステージを追加する構成を示します。

┌─────────────────────────────────────────────────────┐
│ CodePipeline │
├──────────┬──────────┬──────────┬───────────────────┤
│ Source│ Build │ Test  │ Deploy│
│ (GitHub) │ │ │ Lambda + AppConfig │
└──────────┴──────────┴──────────┴───────────────────┘

パイプラインのDeployステージでは、Lambda関数のデプロイと並行してAppConfig構成バージョンを作成します。この際、新しいフィーチャーフラグをenabled: falseの状態で作成しておき、コードのデプロイが完全に完了してから別のステップでフラグをONにするパターンが安全です。

# CodeBuildでの実行例(buildspec.yaml内のpost_buildコマンド)
VERSION=$(aws appconfig create-hosted-configuration-version \
  --application-id $APP_ID \
  --configuration-profile-id $PROFILE_ID \
  --content file://config/feature-flags.json \
  --content-type application/json \
  --query 'VersionNumber' --output text)

# カナリア戦略でデプロイ開始
aws appconfig start-deployment \
  --application-id $APP_ID \
  --environment-id $ENV_ID \
  --deployment-strategy-id Canary10Percent20Minutes \
  --configuration-profile-id $PROFILE_ID \
  --configuration-version $VERSION

GitOpsとの協調

Gitリポジトリでフィーチャーフラグの設定ファイルをコードとして管理するGitOpsアプローチも有効です。

repository/
├── src/  # アプリコード
├── infrastructure/
│└── terraform/ # IaC定義
└── config/
 └── appconfig/
  ├── feature-flags.json # フィーチャーフラグ定義
  └── dynamic-config.json# 動的設定値

config/appconfig/ディレクトリへの変更がプルリクエストでレビューされ、マージ後にCI/CDがAppConfigへ自動的にデプロイする構成です。フラグの変更が誰によっていつ行われたかがGitの履歴として残り、監査証跡の確保にも役立ちます。

7.6 フラグ運用のガバナンス

組織規模でフィーチャーフラグを安全に運用するには、承認フローと監査ログの整備が重要です。

承認フローの設計

AppConfigへの変更を誰でも自由に行えるようにすると、意図しない本番変更のリスクが生じます。IAMポリシーとAWS Organizations SCPを組み合わせて適切なアクセス制御を設けます。

ロール権限
開発者構成バージョンの作成のみ
チームリードデプロイまで
SRE/オペレーター全環境でのデプロイと即時ロールバック
自動化(CI/CD)ステージング環境へのデプロイのみ

本番環境へのデプロイにはチームリードまたはSREの承認を必須とし、開発者が単独で本番フラグを変更できないように制御します。

CloudTrailによる監査ログ

AppConfigへの操作はすべてAWS CloudTrailに記録されます。誰がいつどの構成をデプロイしたかをCloudTrailログで追跡でき、インシデント調査や監査対応に活用できます。

CloudTrailでフィルタリングするイベント名の例を示します。

  • StartDeployment — デプロイ開始
  • StopDeployment — デプロイ停止/ロールバック
  • CreateHostedConfigurationVersion — 構成バージョン作成
  • DeleteHostedConfigurationVersion — 構成バージョン削除

これらのイベントをCloudWatch Logsに転送してアラートを設定すると、予期せぬ本番変更を検知して即座に対応できます。

フラグ棚卸しの自動化

フラグ負債を防ぐために、定期的なフラグ棚卸しを仕組み化します。例えば、構成バージョンの作成から一定期間変更がないフラグをCloudWatchイベントでリストアップし、担当チームに通知する仕組みを構築します。

# 構成バージョンの一覧取得例
aws appconfig list-hosted-configuration-versions \
  --application-id $APP_ID \
  --configuration-profile-id $PROFILE_ID

この自動通知によりフラグの削除タスクをバックログに積みやすくなり、フラグ負債の蓄積を継続的に防止できます。

AppConfig実戦パターン

  • 段階リリース — フラグOFFでデプロイ→カナリアでフラグ段階ON(コード配信と設定切替の分離)
  • キルスイッチ — 障害時にフラグOFFで即座に機能無効化(再デプロイ不要の緊急停止)
  • A/Bテスト — マルチバリアントフラグでセグメント別挙動。運用フラグ(メンテ/レート制限)
  • CI/CD連携 — パイプラインからAppConfig構成をデプロイ(コードと設定の協調配信)

Lambdaでの取得統合はこちら(サーバーレス本番運用)

IaCレベルのフィーチャーフラグはこちら(Terraformブランチ戦略)


8. つまずきポイント・アンチパターン・まとめ

8.0 AppConfig活用の判断基準

AppConfigを導入すべきケースと、他のアプローチを選ぶべきケースを整理します。

判断軸AppConfig推奨代替手段を検討
変更頻度再デプロイなしに随時変更したいリリース時の変更でよく、頻度が低い
安全性要件段階配信・自動ロールバックが必要開発環境のみで影響範囲が限定的
設定の複雑さ構造化されたJSON/YAML設定やフラグ管理が必要シンプルな1〜2個の値のみ
コスト意識API呼び出しコストをキャッシュで管理できる超低コストしか許容できない
ガバナンス設定変更の監査・承認プロセスが必要個人プロジェクトや実験環境

AppConfigを使わなくてよいケース: 起動時に一度だけ読み込む固定設定(DBエンドポイント・証明書パスなど)はSecrets Managerや環境変数が適しています。実行時に変更する必要がない設定にAppConfigを使うと、コストと複雑性だけが増加します。また、変更頻度が月1回以下でCI/CDパイプラインの実行時間が許容範囲内であれば、環境変数 + デプロイで十分です。

AppConfigが最も効果を発揮するケース: フィーチャーフラグで新機能の段階ロールアウト・キルスイッチ操作・A/Bテストを管理する場合、および再デプロイを避けながらレート制限・タイムアウト・許可リストを動的に調整したい場合です。本番障害時に「設定だけを緊急変更して即座に回復したい」ユースケースでは特に高い価値を発揮します。複数チームが同じアプリの設定を独立して管理する場合も、AppConfigの構成階層(Application/Configuration Profile分割)が組織上の境界として機能します。

8.1 つまずきポイント7選

AppConfigを本番導入した際に陥りやすいつまずきポイントを整理します。

① 検証なしデプロイで不正な設定を本番配信してしまう

最も多い事故パターンです。Configuration Profileにバリデーターを設定していない状態で、型エラーや必須フィールド欠落の設定を配信してしまいます。アプリケーション側でパースエラーが発生し、サービス障害につながります。「設定変更はコードデプロイと違って影響が小さい」という思い込みが事故を招きます。

典型的な事故例:
– タイムアウト値を誤って0に設定 → 全リクエストが即座にタイムアウトし障害
– 必須の外部エンドポイントを空文字に設定 → 接続先がなく機能停止
– 数値フィールドに文字列を混入 → アプリ側の型変換で例外多発
– JSONの末尾にコメントを追加 → 標準JSONパーサーで構文エラー

対策: フリーフォーム型にはJSON Schemaバリデーターを必ず設定します。JSONの型・必須フィールド・値の範囲を定義し、不正な設定はデプロイ前にリジェクトされます。ビジネスロジックの検証(例: レート制限値が0以下になっていないか)にはカスタムLambdaバリデーターを追加します。バリデーターは複数設定できるため、まずJSON Schemaで構造を検証し、続いてLambdaでビジネスロジックを検証する2段構えが安全です。

# JSON Schemaバリデーターを追加する例
aws appconfig create-configuration-profile \
  --application-id "APP_ID" \
  --name "rate-limits" \
  --location-uri "hosted" \
  --type "AWS.Freeform" \
  --validators '[
 {
"Type": "JSON_SCHEMA",
"Content": "{\"type\":\"object\",\"properties\":{\"apiRequestsPerMinute\":{\"type\":\"number\",\"minimum\":1}},\"required\":[\"apiRequestsPerMinute\"]}"
 }
  ]'

② CloudWatchアラームをEnvironmentに紐付けていないため自動ロールバックが効かない

AppConfigの自動ロールバックはEnvironmentに紐付けたCloudWatchアラームがトリガーになります。アラームを設定しないと、設定変更によるエラー増加が発生しても自動復旧しません。手動でロールバック操作するまで障害が継続します。「デプロイ戦略にカナリアを選んでいるから安全」と思っていても、アラームが未設定では問題を自動検知できません。

対策: Environmentを作成したら必ずCloudWatchアラームを紐付けます。最低限、アプリケーションのエラー率アラームとレイテンシアラームの2つを設定します。AppConfigがアラームを読み取るためのIAMロール(cloudwatch:DescribeAlarms権限)も忘れずに設定します。アラームのARNと専用IAMロールのARNの両方をMonitorsに指定する必要があります。Infrastructure as Code(Terraform/CDK)でEnvironmentとアラームを一体管理することで、設定漏れをコードレビューで防止できます。

③ 即時デプロイ(AllAtOnce)で全ホストに一括配信し障害を拡大する

AllAtOnce(即時)デプロイ戦略を本番で使用すると、設定変更が全ホストに同時に反映されます。設定に問題があった場合、全ホストで同時に影響を受け、blast radiusは最大になります。JSON Schemaバリデーターを通過した設定でも、アプリのロジックとの組み合わせで予期しない動作を引き起こすことがあります。「設定変更はデプロイと違うから影響は小さい」という認識が危険なアンチパターンです。

対策: 本番Environmentには Linear(リニア・段階的)または Canary(カナリア・指数的)デプロイ戦略を使用します。段階的に配信することで、問題を少数ホストで検出してCloudWatchアラームによる自動ロールバックが機能します。AllAtOnceは開発・ステージング環境に限定し、本番では必ず段階配信戦略を選択します。緊急のキルスイッチ操作(フラグをOFFに切り替える障害停止)のみ、手動監視を前提としてAllAtOnceを使用するのが現実的な運用ルールです。

④ 短命フラグを掃除せずフラグ負債が蓄積する

新機能のリリースに使用したフィーチャーフラグを全面有効化後もコードとAppConfigに残し続けると、フラグ負債が蓄積します。フラグの必要/不要の判断が困難になり、アプリコードのif分岐が増え続けます。フラグが増えるほどコードの可読性が低下し、テストのカバレッジも複雑化します。長期間運用しているサービスでは数十〜百以上のフラグが蓄積して管理不能になるケースがあります。また、古いフラグが意図せず相互作用して予期しない動作を引き起こすリスクもあります。

対策: フラグには有効期限や担当チームをメタデータとして記録し、定期的にフラグ棚卸しを実施します。フラグをON固定で全面展開した後は、コードからフラグ評価ロジックを削除し、AppConfigの構成プロファイルからもフラグを削除します。スプリントの終わりに「このフラグは本当に必要か」をレビューするプロセスを設けることが有効です。フラグの削除はコードから先に行い、デプロイしてAppConfig上のフラグ参照がなくなったことを確認してから、AppConfigのプロファイルからも削除する順序で進めます。

⑤ SDK直接取得でAPI呼出が過多になりコストが増大する

GetLatestConfiguration APIをアプリケーションから直接呼び出す実装では、Lambdaの各invocation・ECSタスクの各リクエスト処理のたびにAPI呼び出しが発生します。大量のLambda呼び出しやECSトラフィックを抱える環境では、AppConfigのAPI呼び出しコストが予想外に膨らみます。1秒あたり1000リクエストを処理するサービスでは、1日で8600万回ものAPI呼び出しを生成します。AppConfigの無料枠を超えた分は課金されるため、本番移行後に想定外の請求を招くケースもあります。

対策: Lambda環境ではAppConfig Lambda extensionを使用します。Extensionがローカルキャッシュとして機能し、設定変更がない限りキャッシュから返すため、API呼び出し回数を大幅に削減できます。ECS/EC2環境ではAppConfig Agentをサイドカーまたはデーモンとして実行します。どちらの場合も、設定変更時のみAPIが呼ばれるため、コストを最小化できます。導入前後でCloudWatchのAppConfigメトリクスを比較し、API呼び出し削減効果を確認することを推奨します。

⑥ ポーリング間隔を短く設定しすぎてコストが増大する

Lambda extension/AgentのキャッシュTTLやポーリング間隔を短く設定しすぎると、AppConfig APIへの呼び出し頻度が増加してコストが上昇します。特にトラフィックが多い環境では無視できない金額になります。設定変更の頻度が低いにもかかわらず数秒間隔でポーリングするのは、APIコストとネットワークトラフィックの無駄です。

対策: キャッシュTTLは45〜90秒が推奨です。設定変更をリアルタイムに反映したい場合でも、30秒以下のポーリング間隔は必要ないケースがほとんどです。フィーチャーフラグの切り替えは最大で数十秒の遅延が許容範囲内であることを確認したうえで間隔を設定します。コスト管理の観点から、CloudWatchのAppConfigメトリクスでAPI呼び出し回数を定期的に確認することを推奨します。ポーリング間隔は環境変数APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS(Lambda extension)または--poll-interval(Agent)で制御できます。

⑦ EnvironmentとCloudWatchアラームの紐付けが本番/ステージングで混在する

複数のEnvironment(本番/ステージング)を管理している場合に、本番Environmentにステージング用のアラームが紐付いていることがあります。本番での設定変更がステージング環境の状態に左右されてロールバックしたり、逆に本番のエラー増加がアラームをトリガーしなかったりと、予期しない動作を引き起こします。Infrastructure as Codeを使わずコンソールで設定を変更した際に、誤ったARNを指定してしまうことが多いパターンです。AppConfig REST APIのレスポンスではアラームのARNが文字列として返るため、ARNが正しいか確認する際は実際のCloudWatchコンソールで対象アラームと照合する必要があります。

対策: EnvironmentとCloudWatchアラームの紐付けを定期的に棚卸しします。Infrastructure as Code(Terraform/CDK)でEnvironmentとアラームを一体で管理し、紐付けの誤りをコードレビューで検出できる体制を整えます。命名規則でEnvironmentとアラームの対応関係が一目でわかるようにすることも有効です(例: appconfig-production-error-rate-alarm)。Environmentのモニター設定を定期的にCLIで確認するコマンドも用意しておくと便利です。

# EnvironmentのCloudWatchアラーム設定を確認
aws appconfig list-environments --application-id "APP_ID" \
  --query 'Items[?Name==`Production`].{Name:Name,Monitors:Monitors}'

7つのつまずきポイントはすべて「設定と安全性の分離」が不完全な状態から発生します。AppConfigを導入する際に最初から正しく設定するだけでなく、定期的な棚卸し(バリデーター設定・アラーム紐付け・フラグ負債・コスト)をルーティンに組み込む運用習慣が長期的な安定稼働につながります。

8.2 アンチパターンと正解

AppConfigを導入する際によく見られるアンチパターンとその解決策を表形式でまとめます。

アンチパターン問題点正解
設定をコードにハードコード変更のたびにコードデプロイが必要。本番変更が遅くリスク大AppConfigで設定を外部化し、再デプロイなしに変更
環境変数で設定管理して毎回再デプロイ設定1件変更するためにECSサービス再デプロイやLambda更新が必要フリーフォーム型プロファイルで動的に更新
バリデーターなしでフリーフォーム設定をデプロイ不正なJSON/YAML/値が本番に配信されてアプリがクラッシュJSON Schemaバリデーター + Lambdaバリデーターで事前検証
AllAtOnce(即時)戦略を本番で使用問題のある設定が全ホストに同時配信されて障害が拡大カナリア/リニア戦略で段階配信し自動ロールバックと組み合わせ
全面展開後もフラグをコードに残し続けるフラグ負債が蓄積してコードの複雑度が増加する全面展開後にコードとプロファイルから使い終わったフラグを削除
SDK直接呼び出しでリクエストごとにAPI取得API呼び出し回数が膨大になりコストが急増Lambda extension / AppConfig Agentでローカルキャッシュを活用
フィーチャーフラグ型の設定をS3に保存しようとするフィーチャーフラグ型はAppConfigホスト型のみ対応。S3指定はエラーフリーフォーム型でS3保管を使用するか、フラグはホスト型で管理

上記のアンチパターンの中でも特に影響が大きいのは「バリデーターなしのデプロイ」「AllAtOnce本番使用」「CloudWatchアラーム未設定」の3つです。この3点を必ず対策することで、AppConfig導入後の本番障害リスクを大幅に低減できます。バリデーターで不正設定を事前ブロックし、段階配信でblast radiusを限定し、アラームで自動復旧する3層の防御が安全なAppConfig運用の核心です。

8.3 本番導入チェックリスト

AppConfigを本番導入する際の確認項目を整理します。導入前にすべての項目を確認し、設定漏れがないことを検証してください。

Applicationとプロファイルの設定
– [ ] Applicationをサービス単位の命名で作成済み(例: ec-sitepayment-service
– [ ] フィーチャーフラグ型のConfiguration Profileを作成し、フラグ定義を登録済み
– [ ] フリーフォーム型のConfiguration ProfileにJSON Schemaバリデーターを設定済み
– [ ] ビジネスロジック検証が必要な場合はLambdaバリデーターも設定済み

Environmentの設定
– [ ] 本番/ステージング/開発の各Environmentを分離作成済み
– [ ] 本番EnvironmentにCloudWatchアラームを紐付け済み(最低: エラー率 + レイテンシの2本)
– [ ] AppConfigがCloudWatchアラームを読み取るIAMロールを設定済み(cloudwatch:DescribeAlarms権限 + 信頼ポリシーappconfig.amazonaws.com
– [ ] Environmentとアラームの紐付けを本番/ステージングで混在させていないことを確認済み

デプロイ戦略の確認
– [ ] 本番EnvironmentでAllAtOnce以外の段階配信戦略(Canary10Percent20MinutesまたはLinear)を設定済み
– [ ] デプロイ時間とbake time(最終ベイク時間)を設定済み(本番: 最低5分以上推奨)
– [ ] ステージング環境で事前デプロイ検証済み

アプリケーション側の設定
– [ ] Lambda環境: AppConfig Lambda extensionのARNをLayers配列に追加済み
– [ ] ECS/EC2環境: AppConfig AgentをサイドカーまたはデーモンとしてECSタスク定義に追加済み
– [ ] キャッシュTTLを環境変数APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDSで設定済み(推奨: 45〜90秒)
– [ ] アプリ側IAMポリシーにappconfig:GetLatestConfigurationappconfig:StartConfigurationSessionを付与済み

フラグ運用の体制
– [ ] フィーチャーフラグに有効期限・担当チームをメタデータとして記録済み
– [ ] フラグ棚卸しのプロセスを定期スプリントレビューに組み込み済み
– [ ] 全面展開後のフラグ削除プロセス(コード削除 → AppConfig削除の順序)を定義済み

コスト管理
– [ ] CloudWatchメトリクスでAppConfigのAPI呼び出し回数モニタリングを設定済み
– [ ] Lambda extensionまたはAppConfig Agentによるキャッシュ有効化を確認済み

8.3.1 コスト最適化の考え方

AppConfigのコストはAPI呼び出し回数と設定データの受信量に基づきます。Lambda extensionやAppConfig Agentによるローカルキャッシュを使用すると、API呼び出し回数を大幅に削減できます。

取得方式1日のAPI呼び出し目安(1インスタンス/45秒ポーリング)備考
SDK直接呼び出し(リクエストごと)毎秒1000呼び出し = 8600万/日キャッシュなし。高コスト
Lambda extension(TTL 45秒)1920回/日45秒ごとにキャッシュ更新チェック
AppConfig Agent(45秒ポーリング)1920回/日サイドカーが代わりにポーリング

ほとんどの設定は45〜90秒ごとの更新チェックで十分です。設定変更が発生していない場合、AppConfigは変更なしの応答(HTTPヘッダーのみ)を返すため、通信量も最小になります。

コスト見積もりの目安として、AppConfig Agent/extensionを使用した場合、インスタンス1台あたりの月額コストは数セント〜数十セント程度です。SDK直接呼び出しでは数百〜数千ドルの差を生じさせる場合があります。正確な金額はAWS料金ページで確認してください。

8.4 本記事のまとめ

AWS AppConfigは「コードはそのまま、設定とフィーチャーフラグだけを安全に変更する」層を提供するマネージドサービスです。再デプロイによるリスクとリードタイムを排除し、機能のON/OFFや設定値の変更をランタイムで即座に適用できます。

本記事Vol1で解説した内容を整理します。

Application/Environment/Configuration Profileの3階層がAppConfigの基盤です。Applicationはサービス単位のコンテナ、EnvironmentはCloudWatchアラームを紐付けたデプロイ先、Configuration Profileはフィーチャーフラグ型(AppConfigホスト型のみ)とフリーフォーム型(S3/SSM Parameter Store等も可)の2種類で設定を定義します。

フィーチャーフラグはコード変更なしに機能のON/OFFを切り替える仕組みです。属性付きフラグで数値や文字列の設定値も持たせられます。マルチバリアントフラグとAppConfig Agentを組み合わせることでセグメント別の段階的ロールアウトを実現できます。フラグは使い終わったら速やかに削除し、フラグ負債を防ぎます。

フリーフォーム型の動的設定は、JSON/YAML/テキストの任意設定を再デプロイなしに変更する仕組みです。JSON SchemaバリデーターとカスタムLambda検証でデプロイ前に設定の正確性を担保し、不正な設定の本番配信を防止します。バージョン管理で変更履歴が保持され、任意バージョンへのロールバックが可能です。

デプロイ戦略(カナリア/リニア)とCloudWatchアラーム自動ロールバックがAppConfigの安全性の核心です。段階配信でblast radiusを限定し、アラームがトリガーされた瞬間に前バージョンへ自動復帰します。

Lambda extensionとAppConfig Agentがコスト最適化の鍵です。ローカルキャッシュを活用することでAPI呼び出し回数を削減し、設定取得のレイテンシも低減します。

AppConfigが解決する根本課題は「設定変更のたびにコードをデプロイしなければならない」問題です。このアプローチには複数のリスクがあります。まず、設定変更とコード変更を同時にデプロイするため、問題が発生した際に原因の切り分けが困難になります。次に、緊急の設定変更(レート制限の引き下げ・機能のキルスイッチ)に対して、CI/CDパイプラインを経由する必要があり、対応時間が長くなります。AppConfigによる設定の外部化は、コードのライフサイクルと設定のライフサイクルを分離し、それぞれを独立して管理できる設計を実現します。

運用ガバナンスの観点から、AppConfigはCloudTrailを通じて全ての設定変更を監査ログとして記録します。誰が・いつ・どの設定を・どのバージョンに変更したかが追跡可能であり、コンプライアンス要件や障害対応の事後分析に活用できます。また、IAMポリシーで特定のEnvironment(本番のみ)への設定デプロイを特定のIAMロールにのみ許可する設計も可能です。

AppConfigを単なる設定ストアとして使うのではなく、デプロイ戦略・バリデーター・自動ロールバック・段階配信を組み合わせた安全な設定変更基盤として運用することで、障害リスクを最小化しながら素早い機能制御を実現できます。

8.5 Vol2予告

Vol2では以下のトピックを深掘りします。

AppConfig Agent高度設定: セグメント定義(ユーザー属性・デバイス種別・地域別)による粒度の細かいロールアウト制御、個別ユーザー単位での段階的フラグ展開、動的フラグ評価のベストプラクティスを解説します。

CI/CDパイプラインとの統合: CodePipelineを使ってコードのデプロイと設定変更を協調させる統合パターン、承認ゲート(手動承認アクション)を挟んだ安全な設定デプロイ、GitOps(GitリポジトリをSingle Source of Truthとした設定管理)との連携を扱います。

マルチアカウント/マルチリージョン展開: AWS OrganizationsとAppConfigを組み合わせた組織全体の設定管理、クロスリージョンでの設定配信とフェイルオーバー設計、複数環境(dev/stg/prod)での設定の昇格(promotion)プロセスを解説します。

監視・ガバナンス: CloudTrailによる設定変更の完全な監査証跡の活用方法、IAMによるEnvironment単位の権限制御(本番環境のデプロイを限られたロールのみに制限)、AWS Configルールによるコンプライアンス検証を深掘りします。

Vol1で習得したAppConfigの基礎(構成階層・フラグ・動的設定・デプロイ戦略・自動ロールバック)をもとに、Vol2では実際の本番規模での運用パターンと、組織・チーム横断でのAppConfig活用戦略を解説します。コードのデプロイと設定の動的配信を組み合わせた現代的なプログレッシブデリバリーの全体像を理解し、ゼロダウンタイムでの機能展開基盤を構築できるようになります。


本記事のまとめ

  • AppConfigは再デプロイ不要で設定/フィーチャーフラグをランタイム配信・切替するマネージドサービス
  • 構成階層(Application/Environment/Configuration Profile)+検証(JSON Schema/Lambda)で安全に管理
  • デプロイ戦略(カナリア/リニア)+CloudWatchアラーム自動ロールバックがblast radiusを限定
  • 取得はLambda extension/Agentでローカルキャッシュ。キルスイッチ/段階リリース/A-Bテストに活用