CertNote/ Commute Study Notes
Roadmap
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
  • Week 1
    • 1.DevOps as an Operating Model: The Five Axes of CALMS and the Truth DORA Proved Through Measurement
    • 2.Well-Architected Framework: Rereading It Through the Six Lenses of DevOps
    • 3.The AWS DevOps Tool Map: The Code* Series and the Real Picture Beyond It
    • 4.Multi-Account Strategy: The Real Picture of Organizations, Control Tower, and IAM Identity Center
    • 5.Week 1 Wrap-Up: Cementing the DevOps Thinking Frame with Scenarios
  • Week 2
  • Week 3
  • Week 4
  • Week 5
  • Week 6
  • Week 7
  • Week 8
  • Week 9
    • 1.Systems Manager: Run Command·Session Manager·Patch Manager's Deep Story
    • 2.State Manager·Inventory·Compliance: The Abstraction of Desired State
    • 3.AppConfig: The Art of Changing Behavior Without a Code Deployment
    • 4.Secrets Manager and Parameter Store: Lifecycle and Rotation
    • 5.Week 9 Integrated Review: Operations Automation as One Picture
  • Week 10
  • Week 11
  • Week 12
  • Week 13
  • Week 14
  • Week 15
  • Week 16
Linux Master 2 · 2급KAIT Linux Master - Level 2
SCS-C03 · SpecialtySecurity - Specialty
Linux Master 1 · 1급KAIT Linux Master - Level 1
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
MLS-C01 · SpecialtyMachine Learning - Specialty
SQLD · 개발자SQL Developer (SQLD)

© CertNote · 주간랩스

  • About
  • Changelog
  • Contact
  • Terms
  • Privacy
← DOP-C02/Week 9/Day 3

Based on the DOP-C02 exam guide·Report an error

DOP-C02· ProWeek 9 · Day 3~45 min read

Day 3 - AppConfig: The Art of Changing Behavior Without a Code Deployment

Deployment is risky. The moment you push new code to prod, you can't fully know what will happen, and if something goes wrong you have to perform another deployment called a rollback. But if you look closely, much of what we want to change in prod isn't the code itself. "Should we turn this new feature on or off?" "Should the retry count be 3 or 5?" "Should we show this promotion to only 10% of users?" These are changes of behavior, not changes of logic. Yet traditionally, even one of these small behavior changes meant going through a full code redeployment.

AppConfig unties this knot. It separates configuration from code and makes it external data (configuration as data), and then changes that data gradually without redeploying code. Turning on a feature flag, adjusting a threshold, and exposing a promotion to only some users all happen without a git push or a Lambda redeployment. Today we look at why this configuration-as-data is powerful, why AppConfig's five-element structure is divided the way it is, how pre-deployment validation (Validator) and in-flight automatic rollback (Monitor) make a "configuration change" "as safe as a code deployment," and how the Lambda Extension reduces cost and latency with the small trick of localhost:2772. On the DOP exam, "turn a feature on/off without a code deployment" and "gradual activation 10% → 100% + automatic rollback on alarm" are almost always AppConfig.

Configuration as Data: Separating Code from Configuration

"What goes in the code and what gets pulled out into configuration?" is an old question in software. The principle is to pull out into configuration the values that change often, that you want to change without a deployment, and that differ per environment. The 12-Factor App methodology nailing down "store config in the environment" is in the same vein.

But environment variables have limits. To change an environment variable you have to restart the process (= redeploy), you can't apply it gradually (everything changes at once), and there is no validation to stop a wrong value. AppConfig lifts configuration from an "environment variable" to "external data fetched dynamically at runtime." The application polls for configuration periodically while running, not just at startup, and reflects the latest value. Behavior changes without a restart.

This is the foundation of the feature flag (feature toggle). You plant only a branch in the code (if flag.enabled) and control whether that branch is on or off through external configuration. You deploy the new feature's code to prod in advance but leave it turned off with the flag (a dark launch), and when you're ready you flip only the flag to activate it. Deployment and release are decoupled, and this is a core technique of modern continuous deployment.

💡 Related theory: The separation of deploy and release is a core principle of trunk-based development and continuous deployment. It is a concept established in Martin Fowler's writing, and it treats putting code into prod (deploy) and exposing a feature to users (release) as separate acts. Feature flags make this separation possible. You can merge and deploy even an unfinished feature to trunk with its flag off, which avoids the merge hell of long-lived branches. AppConfig provides these feature flags as a managed service, and on top of a simple on/off it adds gradual rollout and even automatic rollback.

⚠️ Trap: Feature flags are powerful, but if unmanaged they become technical debt. If you leave the flag of a finished feature unremoved, branches like if oldFlag ... else if newFlag ... accumulate in the code, and testing every combination of paths becomes impossible. Each flag doubles the number of code paths, so N flags create up to 2^N combinations. That is why AppConfig's feature flag format has _deprecation metadata: it is a signal to track and remove flags that have reached the end of their life. The moment a "temporary flag" becomes a "permanent flag," the debt begins.

The Five Elements of AppConfig: Why Is It Divided This Way?

When you first look at AppConfig, the structure feels complicated. For a single deployment you need all five concepts: Application, Environment, ConfigurationProfile, ConfigurationVersion, and DeploymentStrategy. Why was it split so finely? Because each one separates a different axis of variability.

Application (e.g., checkout-api)         ← Which app's configuration is this
  ├─ Environment (dev / staging / prod) ← Which environment are we deploying to (the alarm monitor attaches here)
  └─ ConfigurationProfile (featureflags / app-settings) ← What are we configuring (the Validator attaches here)
       └─ Hosted / SSM Parameter / S3 / Secrets Manager  ← Where is it stored
  • Application: The owner of the configuration (which service). A logical group.
  • Environment: The target environment for deployment. The CloudWatch alarm monitor attaches here, so you set up automatic rollback with different alarms per environment.
  • ConfigurationProfile: The kind of configuration and where it is stored, and the Validator attaches here. You choose a Feature Flag type (structured flags) or a Freeform type (arbitrary JSON/YAML).
  • ConfigurationVersion: A specific version of the configuration. The version goes up every time you create a new value; a rollback means reverting to the previous version.
  • DeploymentStrategy: How to spread it (immediately / gradually / canary).

The key to this separation is that alarms attach to the environment and validation attaches to the configuration profile. Even if you deploy the same configuration profile (featureflags) to dev and prod, you can set a strict 5xx alarm only on the prod environment so that automatic rollback works there. The validation logic (Validator) applies identically to any environment, because a wrong format must be blocked in dev and prod alike. It is a design that puts things with different axes of variability into different concepts.

The storage backend of a ConfigurationProfile (Hosted/SSM/S3/Secrets Manager) is chosen according to the size and nature of the configuration. Hosted Configuration is the simplest choice, versioned directly by AppConfig, and suits small feature flags and settings. Use SSM Parameter when you already use Parameter Store, S3 when the configuration is large, close to 10MB, and Secrets Manager when it contains secrets. What matters is that whichever backend you use, AppConfig's deployment strategy, validation, and rollback mechanisms apply the same way. AppConfig is not a store but a "deployment orchestrator": its real job is to deploy that value safely and gradually, wherever you keep it.

Deployment Strategy: The Math of the Canary

What decisively separates AppConfig from a simple key-value store is the Deployment Strategy. Instead of applying a configuration change to 100% at once, it spreads it gradually over time.

aws appconfig create-deployment-strategy \
  --name Canary10Percent20Minutes \
  --deployment-duration-in-minutes 20 \
  --growth-factor 10 --growth-type LINEAR \
  --final-bake-time-in-minutes 10 \
  --replicate-to NONE

Here is what these numbers mean. growth-type LINEAR + growth-factor 10 + duration 20 means "increase linearly by 10% at each step over 20 minutes." The proportion of polling clients that receive the new configuration moves over time like this.

LINEAR, growth-factor 10, duration 20 min:
T+0 min:  10% of clients get the new configuration
T+2 min:  20%
T+4 min:  30%
...
T+18 min: 100%
T+20 min: deployment complete → final bake begins
T+30 min: bake complete (alarms are watched for these 10 minutes; automatic rollback if one fires)

If you change to growth-type EXPONENTIAL, the growth is exponential (2% → 4% → 8% → 16% ...). It minimizes risk by exposing only a very small percentage at first and then spreads quickly toward the end. It is a curve closer to a canary. final-bake-time-in-minutes 10 is the soak time during which alarms are watched for 10 minutes even after reaching 100%; if a problem signal is caught during this time, it rolls back automatically.

Predefined strategyCurveUse
AppConfig.AllAtOnce100% immediatelyNon-risky changes, fast application
AppConfig.Linear50PercentEvery30SecondsFast two stepsFast validation in dev/staging
AppConfig.Canary10Percent20MinutesConservative gradualRisky changes in prod

The name canary deployment comes from the canary in a coal mine. Just as miners took canaries, which are sensitive to toxic gas, and detected danger when the bird collapsed first, you expose the new version first to part of the traffic (the canary) to detect problems early. Growth-factor and duration quantify "how slowly will you raise the exposure percentage?" The more slowly you raise the exposure percentage, the sooner you find problems with little impact, but the longer the deployment takes. This also connects to statistical power: more traffic has to pass through the new version before a rare anomaly like 5xx shows up as statistically significant. Canary percentage and bake time are a trade-off between "detection confidence vs. deployment speed."

AppConfig's gradual rollout is polling-based, so its mechanism differs from CodeDeploy's traffic shifting. CodeDeploy adjusts load balancer weights to send "X% of traffic to the new version." In AppConfig, when a client polls, the AppConfig service decides "do you belong to the new configuration group?" and responds. That is, it is a division of the set of polling clients, not a traffic distribution. So AppConfig's gradual rollout creates a situation where multiple instances/Lambdas running the same code receive different configuration values. An important premise is that the application must be able to tolerate temporary inconsistency in configuration values (some with the new value, some with the old).

Validator and Monitor: Making Configuration Changes as Safe as Code Deployments

Changing configuration without a code deployment is a double-edged sword. It is fast and convenient, but it also means bypassing the test and review gates of CI/CD. What stops someone from mistakenly entering "thirty" (a string) or a negative number for timeoutSec? AppConfig covers the risk of this bypass with two layers of safeguards: validation before deployment (Validator) and monitoring during deployment (Monitor).

The Validator automatically validates the configuration before the deployment starts. There are two kinds.

// JSON Schema Validator — format and range validation
{
  "type": "object",
  "required": ["maxRetry", "timeoutSec"],
  "properties": {
    "maxRetry":   {"type": "integer", "minimum": 1, "maximum": 10},
    "timeoutSec": {"type": "integer", "minimum": 1, "maximum": 300}
  }
}

JSON Schema validates the configuration's format, required fields, and value ranges declaratively. If timeoutSec isn't an integer or exceeds 300, the deployment doesn't even start. More complex business rules (for example, "if flag A is on, B must be off") are validated by a Lambda Validator, which receives the configuration content and returns SUCCESS/FAILURE.

The Monitor watches CloudWatch alarms during and after deployment. If you register alarms on the Environment, the moment such an alarm goes into the ALARM state during a gradual deployment or during the final bake, AppConfig automatically rolls back to the previous version.

aws appconfig update-environment \
  --application-id $APP_ID --environment-id $ENV_ID \
  --monitors '[
    {"AlarmArn":"arn:aws:cloudwatch:...:alarm:5xxErrorRate"},
    {"AlarmArn":"arn:aws:cloudwatch:...:alarm:LatencyHigh"}
  ]'

These two layers are the key. The Validator blocks "wrong values going in" beforehand, and the Monitor catches "values that are correct but worsen operational metrics" afterward. A change that passes the format but is bad for the business, for example suddenly exposing everyone with rolloutPercent: 100 and seeing 5xx explode, is automatically reverted by the Monitor when it sees the alarm. It applies to configuration changes exactly the same two-stage defense as code deployment's "tests (before) + canary monitoring (after)."

🎯 Scenario: "The marketing team wants to turn a promotion banner on and off without a code deployment. However, if a wrong setting increases 5xx on the checkout page, it must automatically revert." The answer is an AppConfig Feature Flag profile + a JSON Schema Validator (validating the settings format) + registering a 5xx alarm Monitor on the prod Environment + a Canary gradual deployment strategy. The marketing team just creates a new hosted configuration version and starts the deployment. Format errors are blocked beforehand by the Validator, and operational degradation is blocked afterward by the Monitor. You change behavior safely even without code deployment permissions.

The incident that showed the danger of feature flags was Knight Capital in 2012 (from the era before AppConfig, but the lesson is the same). A reused flag bit woke up old trading logic that should have been disabled, and the firm lost 440 million dollars in 45 minutes. The lesson is that without validation, gradual application, and automatic rollback, a flag change can be even more dangerous than a code deployment. AppConfig's Validator + gradual deployment + Monitor automatic rollback is exactly the device to structurally block this kind of scenario where "a flag change is applied to everything at once and blows up."

Lambda Extension: Cost Optimization with localhost:2772

How does the application fetch AppConfig configuration? The simplest way is to call GetLatestConfiguration with the AppConfig SDK every time. But this has two problems. First, in an environment like Lambda where invocations surge, a huge number of function instances hit the AppConfig API at the same time, raising cost and throttle risk. Second, every invocation adds an API round-trip latency.

The AppConfig Lambda Extension solves this problem elegantly. When you attach the Extension as a Lambda layer, a small sidecar process starts next to the function that polls AppConfig periodically in the background and caches the latest value. The function code fetches the cached value not from external AppConfig but from http://localhost:2772 inside the same execution environment.

Resources:
  MyFn:
    Type: AWS::Serverless::Function
    Properties:
      Layers:
        - !Sub 'arn:aws:lambda:${AWS::Region}:027255383542:layer:AWS-AppConfig-Extension:67'
      Environment:
        Variables:
          AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS: 45
import json, urllib.request
CONFIG_URL = ('http://localhost:2772/applications/checkout-api'
              '/environments/prod/configurations/featureflags')
 
def get_config():
    with urllib.request.urlopen(CONFIG_URL) as r:
        return json.loads(r.read())

POLL_INTERVAL_SECONDS: 45 means the Extension fetches a new value from AppConfig every 45 seconds. Even if the function is invoked thousands of times per second, the AppConfig API is called only once every 45 seconds. A cache hit is a localhost call, so latency is nearly nil too. On EC2, ECS, and EKS, you run the same Extension as a daemon or sidecar and use the same localhost:2772 interface.

The polling interval is a trade-off. A short one reflects configuration changes quickly but increases AppConfig API calls (= Configuration Session cost) and load, while a long one reduces cost but slows the reflection of new configuration. During a gradual deployment, the polling interval becomes "the resolution at which each client receives the new configuration," so you should set it sufficiently shorter than the duration for the gradual curve to be drawn as intended.

AppConfig bills based on Configuration Sessions. The Extension's polling is itself a session call, so "polling interval × number of concurrent execution environments" governs cost. Lambda has a separate execution environment (= a separate Extension) for each concurrent execution, but within each environment the Extension shares its cache, so not every function invocation hits the API. So the real cost is closer to "number of concurrent execution environments × (duration / poll-interval)" than to "100 million function invocations." That setting the polling interval too short makes costs spike for highly concurrent functions is a trap that also appears on the exam.

The Boundary with Evidently: Operational Flags vs. Experiments

The service most often compared with AppConfig is CloudWatch Evidently. Both do gradual exposure and feature flags, but their purposes differ.

ItemAppConfigCloudWatch Evidently
PurposeOperational configuration + feature flags + safe deploymentA/B experiments + statistical significance analysis
AnalysisDelegated to external (CloudWatch/X-Ray)Built-in statistics (conversion rate, confidence interval)
User segmentsHandled in codeBuilt-in segments/targeting
Automatic rollback✅ (alarm Monitor)Experiment stop

AppConfig is an operations tool that says "turn this feature on safely and revert if operational metrics get worse." Evidently is an experimentation tool that measures "which of version A and B has a statistically significantly higher conversion rate?" However, since 2024 Evidently has been heading in a direction where new use is not recommended, so the trend is to consolidate even experimentation into AppConfig + external analysis. On the exam, you can distinguish them as "safe gradual deployment and automatic rollback = AppConfig" and "statistical A/B experiments = Evidently."

An A/B test is statistical hypothesis testing. It judges whether the difference in metrics between two variants (A/B) is by chance or real using p-values and confidence intervals. Evidently has this statistics built in because sufficient samples and a significance judgment are the essence of an "experiment." AppConfig's gradual deployment, by contrast, is not hypothesis testing but risk management: the goal is to "find problems with little impact and revert if they occur." Even for the same "gradual exposure," one aims at statistical learning and the other at safe operations, and that is what fundamentally separates the two services.

Summary

Today's picture has five parts. First, AppConfig is configuration as data, separating configuration from code and serving as the foundation of the feature flags that decouple deploy and release, but flags past their lifetime become debt and must be cleaned up. Second, the five-element structure is a design that separates axes of variability, with the alarm Monitor attached to the Environment and the Validator attached to the ConfigurationProfile. Third, the Deployment Strategy's growth-factor, duration, and bake-time are the math of the canary, and since it divides the set of polling clients, the application must tolerate temporary configuration inconsistency. Fourth, the two layers of Validator (format validation beforehand) + Monitor (automatic alarm-based rollback afterward) make configuration changes as safe as code deployments. Fifth, the Lambda Extension provides a cache at localhost:2772, letting you tune cost and freshness with the polling interval.

In the next post we move on to secrets, another axis of configuration. We look at the boundary between Parameter Store and Secrets Manager, and how the tricky problem of zero-downtime rotation is solved with alternating users.

📝 Practice Questions

Click a choice to reveal the answer and explanation.

Question 1

"The marketing team must gradually activate a feature from 10% → 100% without a code deployment, and it must roll back automatically if checkout 5xx increases." What is the most appropriate service?

Question 2

In AppConfig, to which component does the Monitor for CloudWatch alarm-based automatic rollback attach?

Question 3

What is the most efficient way to use AppConfig configuration in Lambda?

Question 4

What does final-bake-time-in-minutes 10 in a Deployment Strategy mean?

Question 5

What are the two kinds of AppConfig Validators?

Question 6

What situation must an application be able to tolerate during an AppConfig gradual deployment?

Question 7

To measure "which of version A and B has a statistically significantly higher conversion rate," what is more suitable than AppConfig?

📌 Today's Summary

There are five key points today. First, AppConfig is configuration as data, separating configuration from code and serving as the foundation of the feature flags that decouple deploy and release, and flags past their lifetime become 2^N combination debt and must be cleaned up. Second, the five elements (Application/Environment/ConfigurationProfile/Version/Strategy) are a design that separates axes of variability, with the alarm Monitor attached to the Environment and the Validator attached to the ConfigurationProfile. Third, the Deployment Strategy's growth-factor, duration, and bake-time are the math of the canary, and since it divides the set of polling clients, you must tolerate temporary configuration inconsistency. Fourth, the two-stage defense of the Validator (format validation beforehand) and the Monitor (automatic alarm-based rollback afterward) makes configuration changes as safe as code deployments. Fifth, the Lambda Extension tunes cost and freshness through the polling interval with its localhost:2772 cache, and AppConfig (operational safety) and Evidently (statistical experiments) have different purposes.

PreviousState Manager·Inventory·Compliance: The Abstraction of Desired StateWeek 9 · Day 2Next Secrets Manager and Parameter Store: Lifecycle and RotationWeek 9 · Day 4

Official references

  • DOP-C02 official exam page(opens in a new tab)
  • AWS Lambda documentation(opens in a new tab)
  • Amazon CloudWatch documentation(opens in a new tab)
  • Amazon S3 documentation(opens in a new tab)
  • AWS Secrets Manager documentation(opens in a new tab)
  • AWS CodeDeploy documentation(opens in a new tab)

On this page

  • Configuration as Data: Separating Code from Configuration
  • The Five Elements of AppConfig: Why Is It Divided This Way?
  • Deployment Strategy: The Math of the Canary
  • Validator and Monitor: Making Configuration Changes as Safe as Code Deployments
  • Lambda Extension: Cost Optimization with localhost:2772
  • The Boundary with Evidently: Operational Flags vs. Experiments
  • Summary
  • Practice Questions
  • Today's Summary