-
Notifications
You must be signed in to change notification settings - Fork 4
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 toggles rule engine - make AWS AppConfig great again #23
Comments
@heitorlessa After our chat in slack, I thought i'd advance this by providing a working poc with most of the tests. It's pure python, no pydantic! |
Update: working on documentation as we speak |
I'm available on Slack for questions |
This is now launched as part of 1.19.0 release: https://github.com/awslabs/aws-lambda-powertools-python/releases/tag/v1.19.0 |
The UX has largely changed and it's now broken down into the following components:
StoreProvider will likely change to make it easier to bring additional providers - AppConfig is the only supported one as we speak. AppConfigStore is using Full docs with examples are here: https://awslabs.github.io/aws-lambda-powertools-python/latest/utilities/feature_flags/ Current UXSample feature flag schema config{
"premium_features": {
"default": false,
"rules": {
"customer tier equals premium": {
"when_match": true,
"conditions": [
{
"action": "EQUALS",
"key": "tier",
"value": "premium"
}
]
}
}
},
"ten_percent_off_campaign": {
"default": false
}
}
Evaluate single feature flagfrom aws_lambda_powertools.utilities.feature_flags import FeatureFlags, AppConfigStore
app_config = AppConfigStore(
environment="dev",
application="product-catalogue",
name="features"
)
feature_flags = FeatureFlags(store=app_config)
def lambda_handler(event, context):
# Get customer's tier from incoming request
ctx = { "tier": event.get("tier", "standard") }
# Evaluate whether customer's tier has access to premium features
# based on `has_premium_features` rules
has_premium_features: bool = feature_flags.evaluate(name="premium_features",
context=ctx, default=False)
if has_premium_features:
# enable premium features
... Evaluate and return all enabled feature flagsfrom aws_lambda_powertools.event_handler.api_gateway import ApiGatewayResolver
from aws_lambda_powertools.utilities.feature_flags import FeatureFlags, AppConfigStore
app = ApiGatewayResolver()
app_config = AppConfigStore(
environment="dev",
application="product-catalogue",
name="features"
)
feature_flags = FeatureFlags(store=app_config)
@app.get("/products")
def list_products():
ctx = {
**app.current_event.headers,
**app.current_event.json_body
}
# all_features is evaluated to ["geo_customer_campaign", "ten_percent_off_campaign"]
all_features: list[str] = feature_flags.get_enabled_features(context=ctx)
if "geo_customer_campaign" in all_features:
# apply discounts based on geo
...
if "ten_percent_off_campaign" in all_features:
# apply additional 10% for all customers
...
def lambda_handler(event, context):
return app.resolve(event, context) Rule engine and Schema specSchema specification: https://awslabs.github.io/aws-lambda-powertools-python/latest/api/utilities/feature_flags/index.html#aws_lambda_powertools.utilities.feature_flags.SchemaValidator Rule engine flowchart |
I'll keep this open until we go GA so it's easier to catch up on interfaces and such for future implementations ;) |
Key information
Summary
[summary]: Simplify the usage of feature toggles with AppConfig. Take it to the next level with a rule engine that provides calculated values of feature toggles according to input context.
Motivation
App config is great but it's very raw/barebones. This feature will encourage people to use AppConfig.
I'd like to build a feature toggles on top the current app config utility.
Proposal
Build a simple feature toggle rule engine. The rules will be part of the JSON schema that is uploaded to AppConfig. The rule engine will use existing powertools utility to load and parse the json from AppConfig.
It will provide a simple function (same API as launch darkly support) for getting a feature toggle by name. The function will also receive a context dict which will be matched against a set of rules. The feature will have a default boolean value. However, if the context data matches a rule in the schema JSON, the returned value will be the value that is defined in the matched rule.
This can allow you to have a feature toggle turned off by default but turning it on for a specific user or customer in a specific region etc.
The rules will accept any key/value context.
Supported actions can be equals, starts with, regex match , endswith, in a list and many more. It's very easy to extend the engine.
An example rule: 'if customer_name' equals coca cola and username starts with 'admin' , trigger the feature on. For other cases, the feature is off. See configuration language below.
This type of API will take appconfig to the next level. It's very much barebones at the moment.
If this feature should be available in other runtimes (e.g. Java, Typescript), how would this look like to ensure consistency?
It can be done in other languages, it's a very simple rule engine that I've already written in Python.
User Experience
How would customers use it?
conf_store: ConfigurationStore = ConfigurationStore(
environment='test_env',
service='test_app',
conf_name="test_conf_name",
cache_seconds=600,
)
toggle: bool = conf_store.get_feature_toggle(feature_name='my_feature', rules_context={'customer_name': 'coca-cola', 'username': 'abc'}, default_value=False)
The default value parameter in the API is the default value to return if the feature doesn't exist in the json schema.
Any configuration or corner cases you'd expect?
Example configuration:
{
'log_level': 'DEBUG',
'features': {
'my_feature': {
'default_value':
'False',
'rules': [
{
'name':
'set the toggle on for customer name 666 and username abc ',
'default_value':
True,
'restrictions': [
{
'action': 'EQUALS',
'key': 'customer_name',
'value': 'coca-cola',
},
{
'action': 'EQUALS',
'key': 'username',
'value': 'abc',
}
]
},
]
}
}
}
Drawbacks
Current solution has support for only boolean values for feature toggles. This can be of course expanded if required rather easily.
Rationale and alternatives
Alternative is to use a third party tool (which is not free) like Launch Darkly.
What other designs have been considered? Why not them?
You can use Launch Darkly. However, this solution is very simple and provides the same client side API that launch darkly provide with AWS AppConfig.
What is the impact of not doing this?
Unresolved questions
The text was updated successfully, but these errors were encountered: