Managing Configuration with Context
Relevant source files
The following files were used as context for generating this wiki page:The AWS Cloud Development Kit (CDK) provides a powerful mechanism called "Context" for passing configuration values and settings to a CDK application. Context values are key-value pairs that can be supplied from various sources, including files and the command line. This allows for creating flexible and reusable constructs and stacks that can behave differently based on the environment they are being deployed to, without requiring code changes.
A primary use case for context is to supply values that are determined at synthesis time, such as the availability zones in an AWS account or the ID of an existing Amazon Machine Image (AMI). Context is also the mechanism used by the CDK framework to manage feature flags, which enable a controlled rollout of new behaviors and breaking changes. The CDK CLI provides dedicated commands for viewing and managing the context values associated with an application.
Sources: packages/aws-cdk/lib/init.ts:182-198, packages/aws-cdk/lib/commands/context.ts
Core Concepts
Context Sources and Precedence
Context values are resolved from multiple sources with a defined order of precedence. Values from a source with higher precedence will override values from sources with lower precedence.
The following diagram illustrates the resolution order for context values.
This diagram shows that command-line arguments have the highest precedence, followed by cdk.context.json, and then cdk.json.
| Source | Description |
|---|---|
| CLI Arguments | Values passed directly via the --context or -c flag (e.g., cdk synth -c key=value). This has the highest precedence. |
cdk.context.json | A file automatically generated and managed by the CDK CLI. It is used to cache context values retrieved from the environment by Context Providers. This prevents values from changing between runs, which could lead to unexpected infrastructure changes. |
cdk.json | The main project configuration file. Static context values can be defined within the context object in this file. |
| Project Defaults | Default values, such as future flags, that are automatically injected into the context. For example, cdk init adds future flags to the cdk.json file. |
Sources: packages/aws-cdk/lib/init.ts:182-198, packages/aws-cdk/lib/settings.ts
Future Flags
A key application of the context mechanism is the management of "Future Flags". These are special context keys that enable new, and sometimes breaking, behaviors in the CDK. When a new CDK project is created using cdk init, a set of current future flags is automatically added to the context section of the cdk.json file. This ensures that new projects start with the latest recommended behaviors.
An example of future flags being added to cdk.json during project initialization:
// packages/aws-cdk/lib/init.ts:182-198
private async applyFutureFlags(projectDir: string) {
const cdkJson = path.join(projectDir, 'cdk.json');
if (!await fs.pathExists(cdkJson)) {
return;
}
const futureFlags: {[key: string]: any} = {};
Object.entries(cxapi.FUTURE_FLAGS)
.filter(([k, _]) => !cxapi.FUTURE_FLAGS_EXPIRED.includes(k))
.forEach(([k, v]) => futureFlags[k] = v);
const config = await fs.readJson(cdkJson);
config.context = {
...config.context,
...futureFlags,
};
await fs.writeJson(cdkJson, config, { spaces: 2 });
}
Sources: packages/aws-cdk/lib/init.ts:182-198
Context Providers
Context Providers are plugins that allow the CDK to populate context values from the AWS environment during synthesis. For example, a context provider can look up the latest AMI for Amazon Linux or retrieve the VPC ID of a default VPC in your account. When a context provider is used, its output is cached in cdk.context.json to ensure repeatable syntheses.
Provider Interface
All context providers implement the IContextProvider interface, which defines a single method, getValue.
// packages/aws-cdk/lib/context-providers/provider.ts:10-15
export interface IContextProvider {
getValue(props: { [key: string]: any }): Promise<any>;
}
Sources: packages/aws-cdk/lib/context-providers/provider.ts:10-15
The getValue method takes a set of properties as input and returns the resolved value from the environment.
Invocation Flow
The following sequence diagram shows how a context provider is invoked when a CDK app requests a context value that is not already cached.
This diagram illustrates the process of a context provider fetching a value from an AWS API and caching it in cdk.context.json.
Sources: packages/@aws-cdk/core/lib/context-provider.ts, packages/aws-cdk/lib/context-providers/provider.ts
Managing Context with the CLI
The aws-cdk command-line tool provides a dedicated set of commands under cdk context to inspect and manage the context values stored in cdk.json and cdk.context.json.
Sources: packages/aws-cdk/lib/commands/context.ts:24-34
CLI Commands
The cdk context command and its subcommands allow developers to interact with the stored context.
| Command | Description |
|---|---|
cdk context | Displays the full resolved context for the application. |
cdk context --get <KEY> | Retrieves a specific context value by its key. |
cdk context --set <KEY>=<VALUE> | Sets a context value in cdk.json. |
cdk context --reset <KEY> | Removes a value from cdk.context.json, forcing it to be re-evaluated by the context provider on the next synthesis. |
cdk context --clear | Clears all context values from cdk.context.json. |
The implementation of these commands can be found in packages/aws-cdk/lib/commands/context.ts. For example, the handler for the command dispatches to functions like viewContext, setContext, or resetContext based on the provided arguments.
// packages/aws-cdk/lib/commands/context.ts:40-59
export async function handler(args: Arguments): Promise<number> {
const command = args._[1];
if (command !== 'context') {
throw new Error(`Unexpected command: ${command}`);
}
args.command = 'context';
const context = new Context(args);
if (args.reset) {
return context.reset(args.reset);
}
if (args.clear) {
return context.clear();
}
if (args.get) {
return context.get(args.get);
}
// ... more command handling
}
Sources: packages/aws-cdk/lib/commands/context.ts:40-59
Summary
The context system is a fundamental feature of the AWS CDK that provides a robust and flexible way to manage configuration. It decouples environment-specific values from the application code, enabling the creation of reusable and adaptable infrastructure components. Through a clear precedence order, command-line management tools, and the powerful mechanism of context providers, developers can effectively control application configuration, manage feature flags, and interact with their AWS environment at synthesis time.