Cloud Native
Control Tower: Then vs Now
Control Tower today is not the same Control Tower that you may have been introduced to in the past.
One fateful night I was scrolling through Twitter and caught Corey Quinn's (LastWeekInAWS author) AppConfig review:
Hey, I can post videos longer than 2:20 now; here's how I explain AppConfig and get myself hunted down. pic.twitter.com/mvP8zcg4JU
— Corey Quinn (@QuinnyPig) November 11, 2021
As entertaining and sarcastic as it is, his criticisms of the service definitely resonated with me. I can usually use an AWS service's console to get a pretty good idea of how the service expects you to use it, but that understanding is sorely missing from my experience using the AppConfig console. It's not obvious how to actually consume an environment's current configuration - if you take a quick look at the appconfigdata APIs, you'll see start-configuration-session
and get-latest-configuration
. With SSM Parameter Store it's straightforward: get-parameter
is the API to use to consume a parameter. With AppConfig I have to start some nebulous session first? And then after that, I can pull the configuration down? It seems so strange, this seems like a lot of undifferentiated heavy lifting - so I finally decided to do some deep digging to really understand what's going on with this service. Is it a hidden gem? Should more people use it? Let's find out.
There are a few fundamental concepts to understand about the service before we can start understanding more about what the AppConfig team had in mind when they designed this service:
dev
, qa
, prod
, or your-prod
Before you can actually consume configuration, you need to deploy your configuration from a ConfigurationProfile into an Environment. This is where some of the power of AppConfig comes into play. You target an Environment for which you want to update the configuration and select the specific version of the configuration you want to deploy. From there you're able to define or use a deployment strategy to gradually roll your configuration change out over time (so X% of your configuration GET requests will receive the new change, others will receive the old version), then you can deploy the change to that environment.
When defining an AppConfig Environment, you can also tell it to keep an eye on a CloudWatch alarm. If that alarm is triggered during a configuration change (during the bake time), a rollback of that change will be initiated, giving you another layer of safety you can implement with AppConfig.
Before you can deploy configurations, you need to define a ConfigurationProfile. Configuration for a ConfigurationProfile can be sourced from several other AWS services:
By default, we recommend using the AppConfig-Hosted configuration source, as it is likely to provide the least friction way to get started.
AWS CloudFormation supports AWS AppConfig, so you'll want to define your AppConfig Applications, Environments, and ConfigurationProfiles via Infrastructure as Code (IaC), usually logically organized with the application that's consuming it. Because your CloudFormation templates get deployed to each environment, this makes the concept of using AppConfig Environments strange. If you were to use them, you'd have an AppConfig Application defined separate from the rest of your infrastructure, and then define the AppConfig Environment with your application. However, this makes it tricky when you're deploying your application environments to different accounts (AppConfig does not support cross-account access).
Because of this complexity, we recommend treating AppConfig Environments similarly to how we (and many others) treat API Gateway stages. Where you'd usually create one API Gateway per application environment (each with one API Gateway stage), create one AppConfig Application per application environment (each with one AppConfig Environment). This simplifies how we manage these resources via IaC and handle breaking environments into their own accounts.
For a service that's targeted at the application configuration, it's not very obvious how to actually read that configuration. Something I do when I'm learning a new service is to see what kind of API calls there are. Looking at the AWS CLI documentation, I see two "appconfig" API namespaces: appconfig
and appconfigdata
. Since this is going to be a data plane activity, I'm assuming we'll want the appconfigdata
API, which has two actions underneath it: start-configuration-session
and get-latest-configuration
.
To explain the need for these things, it's important to understand how AppConfig handles configuration changes - it supports rolling deployments. Because of this, AppConfig wants to make it clear when your configuration could be "expired" - i.e. when your application boots up it needs to continuously poll for new configuration changes over time, not read it once and call it a day.
The way the service makes this clear is that it expects you to start a "configuration session" which will return a token that you can use in the other API call get-latest-configuration
. When you call get-latest-configuration
, you get a few things:
In your application, you should regularly check for configuration changes and update your code's internal configuration store whenever there are changes.
If you're running on Lambda you're not running some long-running compute resource that can support updating internal configuration, so AWS graciously provides you with a Lambda extension that can handle this polling for you automatically. This reduces the complexity of needing to write your own configuration session code. With it all you need to do is call against a local API via localhost:2772
to get the current configuration which is usually a very fast API call. We've got an example of this in our GitHub here.
It IS complicated. It's not a very simple AWS service, but it does provide you with the capabilities of safer configuration changes through CloudWatch alarm integrations and automatic rollbacks. Depending on the application you're building it may not be worth it to take on this additional complexity (K.I.S.S.!), but if you have a high volume app, if you're concerned about configuration changes in general, or if and want to stay in an AWS Native architecture, AWS AppConfig might be right for you.
Control Tower today is not the same Control Tower that you may have been introduced to in the past.