Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rfc: feature flags #5017

Closed
wants to merge 14 commits into from
34 changes: 22 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,39 +521,49 @@ can be used in these cases.
### Feature Flags

Sometimes we want to introduce new breaking behavior because we believe this is
the correct default behavior for the CDK. The problem of course is that breaking
changes are only allowed in major versions and those are rare.
the correct default behavior for the CDK. However, breaking changes are only allowed
in major versions and those are rare.

To address this need, we have a feature flags pattern/mechanism. It allows us to
introduce new breaking behavior which is disabled by default (so existing
projects will not be affected) but enabled automatically for new projects
created through `cdk init`.

**DISCLAIMER**: feature flags are a "last resort" mechanism and should only be used
when it is impossible to figure out a way to introduce a feature without breaking
existing users. If you think your feature should be implemented behind a feature
flag, you will need to get an approval from at least two core team members. We do that
in order to avoid the abuse of this powerful capability.

The pattern is simple:

1. Define a new const under
1. Seek the approval of a core team member that a feature flag can be used.
eladb marked this conversation as resolved.
Show resolved Hide resolved
eladb marked this conversation as resolved.
Show resolved Hide resolved
* If the feature in question is being planned via an RFC, and the feature flag is contained in the proposal,
core team member approval should include the feature flag.
* If the feature is being tracked in a single issue without an RFC, approval should be indicated in this issue.
2. Define a new const under
[cx-api/lib/features.ts](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/cx-api/lib/features.ts)
with the name of the context key that **enables** this new feature (for
example, `ENABLE_STACK_NAME_DUPLICATES`). The context key should be in the
form `module.Type:feature` (e.g. `@aws-cdk/core:enableStackNameDuplicates`).
2. Use `node.tryGetContext(cxapi.ENABLE_XXX)` to check if this feature is enabled
3. Use `node.tryGetContext(cxapi.ENABLE_XXX)` to check if this feature is enabled
in your code. If it is not defined, revert to the legacy behavior.
3. Add your feature flag to
4. Add your feature flag to
[cx-api/lib/future.ts](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/cx-api/lib/future.ts).
This map is inserted to generated `cdk.json` files for new projects created
through `cdk init`.
4. In your PR title (which goes into CHANGELOG), add a `(under feature flag)` suffix. e.g:
5. In your PR title (which goes into CHANGELOG), add a `(behind feature flag)` suffix. e.g:

```
fix(core): impossible to use the same physical stack name for two stacks (under feature flag)
fix(core): impossible to use the same physical stack name for two stacks (behind feature flag)
```
5. Under `BREAKING CHANGES` in your commit message describe this new behavior:
6. Under `BREAKING CHANGES`, add a prefix `(behind feature flag)` and the name of the flag in the postfix.
For example:

```
BREAKING CHANGE: template file names for new projects created through "cdk init"
will use the template artifact ID instead of the physical stack name to enable
multiple stacks to use the same name. This is enabled through the flag
`@aws-cdk/core:enableStackNameDuplicates` in newly generated `cdk.json` files.
BREAKING CHANGE: (behind feature flag) template file names for new projects created
through "cdk init" will use the template artifact ID instead of the physical stack
name to enable multiple stacks to use the same name (feature flag: @aws-cdk/core:enableStackNameDuplicates)
```

In the [next major version of the
Expand Down
53 changes: 49 additions & 4 deletions design/feature-flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ When we release a new major version of the AWS CDK, we will flip this behavior
or completely remove the legacy behavior.

In order for new projects to pick up this new behavior automatically, we will
modify `cdk init` to inject the set of "future flags" into the generated
modify `cdk init` to inject the set of feature flags into the generated
`cdk.json` file. This means that the new project will have the latest behavior,
but projects that were created prior to the introduction of this feature will
have the same legacy behavior based on the set of capabilities that were
available at the time of the project's creation. This list will be cleaned up
every time we release a major version of course.

Using fine-grained flags will allow users of old projects to pick up specific
new "future" behaviors by manually adding the specific keys to their `cdk.json`
new behaviors by manually adding the specific keys to their `cdk.json`
file, without risking breakage in other unexpected areas.

## Alternative Considered

We considered an alternative of "bundling" new capabilities under a single flag
that specifies the CDK version which created the project, but this means that
users won't have the ability to pick and choose which future capabilities they
users won't have the ability to pick and choose which capabilities they
want to enable in case they need them but don't want to take the risk of
unexpected changes.

Expand Down Expand Up @@ -72,7 +72,45 @@ flag, the CHANGELOG will include:
`cdk init`. It will also indicate the context key this flag uses for users who
wish to enable it manually in their project.

## Future Development
Since feature flags can have implications on framework behavior, we need to
ask users to include the list of enabled features in bug reports. At a minimum,
we can request that they paste a copy of their `cdk.json` and `cdk.context.json`,
but a better experience would be to include this information in the output of
`cdk doctor` and request users to include this output in bug reports.

## Developer Experience
eladb marked this conversation as resolved.
Show resolved Hide resolved

Here's the developer experience:

1. Seek the approval of a core team member that a feature flag can be used.
eladb marked this conversation as resolved.
Show resolved Hide resolved
* If the feature in question is being planned via an RFC, and the feature flag is contained in the proposal,
core team member approval should include the feature flag.
* If the feature is being tracked in a single issue without an RFC, approval should be indicated in this issue.
2. Define a new const under
[cx-api/lib/features.ts](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/cx-api/lib/features.ts)
with the name of the context key that **enables** this new feature (for
example, `ENABLE_STACK_NAME_DUPLICATES`). The context key should be in the
form `module.Type:feature` (e.g. `@aws-cdk/core:enableStackNameDuplicates`).
3. Use `node.tryGetContext(cxapi.ENABLE_XXX)` to check if this feature is enabled
in your code. If it is not defined, revert to the legacy behavior.
4. Add your feature flag to
[cx-api/lib/future.ts](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/cx-api/lib/future.ts).
This map is inserted to generated `cdk.json` files for new projects created
through `cdk init`.
5. In your PR title (which goes into CHANGELOG), add a `(behind feature flag)` suffix. e.g:
```
fix(core): impossible to use the same physical stack name for two stacks (under feature flag)
```
5. Under `BREAKING CHANGES`, add a prefix `(under feature flag)` and the name of the flag in the postfix.
For example:

```
BREAKING CHANGE: (under feature flag) template file names for new projects created
through "cdk init" will use the template artifact ID instead of the physical stack
name to enable multiple stacks to use the same name (feature flag: @aws-cdk/core:enableStackNameDuplicates)
```

## Future Developments

As a general rule, using a feature flag should be last resort in the case where
it is impossible to implement backwards compatibility. A feature flag is likely
Expand All @@ -90,3 +128,10 @@ in the future (as well as any other idea of course):
- Introduce a CLI command to list all flags and enable/disable them in your `cdk.json`.
- Aggregate all flags in groups so it will be easier to enable many of them.
- Define a flag that will allow users to say "I want all feature up until a certain CDK version" (basically enables all features that were available when the version was releases).

## Implementation Plan

- [x] Implement the first feature flag (https://github.com/aws/aws-cdk/pull/4895)
- [x] Update CONTRIBUTING guide with instructions on how to implement feature flags.
- [ ] Add feature flags to `cdk doctor` and update bug report template accordingly to request users to run `cdk doctor`.
- [ ] Document what feature flags are in the CDK Developer Guide, reference cx-api/features.ts, and describe what "BREAKING CHANGE under feature flag" means.