-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
feat: Typescript example of AWS AppConfig hosted configuration with lambda using AppConfig Lambda extension integration #361
Conversation
…lambda extension integration
Title does not follow the guidelines of Conventional Commits. Please adjust title before merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a great potential addition to the examples library, I have a few suggestions that unfortunately may take a bit of effort to add, but I can review additions/fixes incrementally if you would prefer.
My main suggestions revolve around the idea that this needs to be a helpful example, and while the code itself can help people set up their own AppConfig stacks, the lack of explanatory comments makes it a little challenging to grok the reasoning behind it.
Thanks in advance for the contribution!!
😸 😷 🚀
@@ -0,0 +1,89 @@ | |||
import * as cdk from '@aws-cdk/core'; | |||
import { CfnApplication, CfnEnvironment, CfnConfigurationProfile, CfnHostedConfigurationVersion, CfnDeploymentStrategy, CfnDeployment } from '@aws-cdk/aws-appconfig'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should space long imports on separate lines (or import *
and use an accessor
import { CfnApplication, CfnEnvironment, CfnConfigurationProfile, CfnHostedConfigurationVersion, CfnDeploymentStrategy, CfnDeployment } from '@aws-cdk/aws-appconfig'; | |
import { | |
CfnApplication, | |
CfnEnvironment, | |
CfnConfigurationProfile, | |
CfnHostedConfigurationVersion, | |
CfnDeploymentStrategy, | |
CfnDeployment | |
} from '@aws-cdk/aws-appconfig'; |
return [ | ||
{ | ||
name: 'AWS AppConfig' | ||
}, | ||
{ | ||
name: 'Amazon SageMaker Studio' | ||
}, | ||
{ | ||
name: 'Amazon Kendra' | ||
}, | ||
{ | ||
name: 'Amazon CodeGuru' | ||
}, | ||
{ | ||
name: 'Amazon Fraud Detector' | ||
}, | ||
{ | ||
name: 'Amazon EKS on AWS Fargate' | ||
}, | ||
{ | ||
name: 'AWS Outposts' | ||
}, | ||
{ | ||
name: 'AWS Wavelength' | ||
}, | ||
{ | ||
name: 'AWS Transit Gateway' | ||
}, | ||
{ | ||
name: 'Amazon Detective' | ||
} | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can make this a little more condensed while still obeying the eslint rules.
return [ | |
{ | |
name: 'AWS AppConfig' | |
}, | |
{ | |
name: 'Amazon SageMaker Studio' | |
}, | |
{ | |
name: 'Amazon Kendra' | |
}, | |
{ | |
name: 'Amazon CodeGuru' | |
}, | |
{ | |
name: 'Amazon Fraud Detector' | |
}, | |
{ | |
name: 'Amazon EKS on AWS Fargate' | |
}, | |
{ | |
name: 'AWS Outposts' | |
}, | |
{ | |
name: 'AWS Wavelength' | |
}, | |
{ | |
name: 'AWS Transit Gateway' | |
}, | |
{ | |
name: 'Amazon Detective' | |
} | |
] | |
return [ | |
{ name: 'AWS AppConfig' }, | |
{ name: 'Amazon SageMaker Studio' }, | |
{ name: 'Amazon Kendra' }, | |
{ name: 'Amazon CodeGuru' }, | |
{ name: 'Amazon Fraud Detector' }, | |
{ name: 'Amazon EKS on AWS Fargate' }, | |
{ name: 'AWS Outposts' }, | |
{ name: 'AWS Wavelength' }, | |
{ name: 'AWS Transit Gateway' }, | |
{ name: 'Amazon Detective' } | |
] |
<!--BEGIN STABILITY BANNER--> | ||
--- | ||
|
||
![Stability: Stable](https://img.shields.io/badge/stability-Stable-success.svg?style=for-the-badge) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const application = new CfnApplication(this,'AppConfigApplication', { | ||
name: 'AppConfigSampleApplication', | ||
description: 'Sample AppConfig Application using CDK' | ||
}); | ||
|
||
const environment = new CfnEnvironment(this, 'LambdaDevelopmentEnvironment', { | ||
applicationId: application.ref, | ||
name: 'AppConfigSampleLambdaDevelopmentEnvironment', | ||
description: 'Sample AppConfig Development environment for Lambda implementation' | ||
}); | ||
|
||
const configurationProfile = new CfnConfigurationProfile(this, 'ConfigurationProfile', { | ||
applicationId: application.ref, | ||
name: 'AppConfigSampleConfigurationProfile', | ||
locationUri: 'hosted', | ||
description: 'Sample AppConfig configuration profile' | ||
}); | ||
|
||
const hostedConfigurationProfile = new CfnHostedConfigurationVersion(this, 'HostedConfigurationProfile', { | ||
applicationId: application.ref, | ||
configurationProfileId: configurationProfile.ref, | ||
contentType: 'application/json', | ||
content: '{\"boolEnableLimitResults\": true, \"intResultLimit\":5}', | ||
latestVersionNumber: 1 | ||
}); | ||
|
||
hostedConfigurationProfile.addMetadata('description', 'Sample AppConfig hosted configuration profile content'); | ||
|
||
const deploymentStrategy = new CfnDeploymentStrategy(this, 'DeploymentStrategy', { | ||
name: 'Custom.AllAtOnce', | ||
deploymentDurationInMinutes: 0, | ||
growthFactor: 100, | ||
finalBakeTimeInMinutes: 0, | ||
replicateTo: 'NONE', | ||
growthType: 'LINEAR', | ||
description: 'Sample AppConfig deployment strategy - All at once deployment (i.e., immediate)' | ||
}); | ||
|
||
const deployment = new CfnDeployment(this, 'Deployment', { | ||
applicationId: application.ref, | ||
configurationProfileId: configurationProfile.ref, | ||
configurationVersion: '1', | ||
deploymentStrategyId: deploymentStrategy.ref, | ||
environmentId: environment.ref, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider leaving an inline comment to indicate that these are essential components to an AppConfig configuration, and explain what each does along the way.
For inspiration, take a look at the Cloudformation description
description: 'Sample AppConfig Application using CDK' | ||
}); | ||
|
||
const environment = new CfnEnvironment(this, 'LambdaDevelopmentEnvironment', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be useful here to include both a dev and prod environment with appropriate configurations for each. This would show the real power/reason to use AppConfig over a standard deployment strategy.
|
||
deployment.addDependsOn(hostedConfigurationProfile); | ||
|
||
deployment.addMetadata('description', 'Sample AppConfig initial deployment'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, provide in props?
--- | ||
<!--END STABILITY BANNER--> | ||
|
||
This an example of AppConfig fature toggle use case with a hosted configuration and a consuming Lambda using AppConfig Lambda extension integration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be a great place to include a brief description of why this pattern might be useful.
eg. "Deploying an AppConfig resource can allow for easier deployments to multiple environments from development to production and allow for easier changing of necessary configurations depending on environment ...."
deployment.addMetadata('description', 'Sample AppConfig initial deployment'); | ||
|
||
const sampleAppConfigLambda = new Function(this, 'sampleAppConfigLambda', { | ||
code: new AssetCode('src'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By standards this should be:
code: new AssetCode('src'), | |
code: Code.fromAsset('src'), |
This also requires adjusting imports
// retrieve AppConfig configuration data from Lambda extension | ||
const res: any = await new Promise((resolve) => { | ||
http.get( | ||
`http://localhost:2772/applications/AppConfigSampleApplication/environments/AppConfigSampleLambdaDevelopmentEnvironment/configurations/AppConfigSampleConfigurationProfile`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm missing something, but I dont see where this URL is coming from
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this only works with Lambda/ECS/Fargate workloads, normally you would acquire these config values via the AWS SDK: https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions.html#appconfig-integration-lambda-extensions-enabling
There's also this blog post that references the localhost URL proxy: https://aws.amazon.com/blogs/mt/introducing-aws-appconfig-lambda-extension-deploying-application-configuration-serverless/
<!--END STABILITY BANNER--> | ||
|
||
This an example of AppConfig fature toggle use case with a hosted configuration and a consuming Lambda using AppConfig Lambda extension integration. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An explanation of the purpose of the lambda would also be important here. At the moment it is very difficult to decipher (and I imagine even more so for someone with less context than me).
@ScottHand Would you mind addressing NGL321's review? |
This PR has not been touched since before the release of CDKv2. Closing. |
AWS AppConfig hosted configuration example with consuming Lambda using AppConfig Lambda extension integration.
Fixes #360
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.