-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: initial implementation of wso2-application (not tested)
- Loading branch information
1 parent
7eb3238
commit c71af29
Showing
25 changed files
with
1,152 additions
and
435 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
## Construct BaseNodeJsLambda | ||
|
||
Based on [AWS Construct NodeJsFunction](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.NodejsFunction.html) and adds the following capabilities: | ||
- creates a default security group. See property 'defaultSecurityGroup' of this construct | ||
- creates an alias called "live" pointing to the latest lambda version and replaced versions are deleted automatically. See property 'liveAlias' of this construct | ||
- typed configuration props for common usage scenarios | ||
- autoscaling of provisioned concurrent invocations (so you lower cold starts). You can also use automatic scheduling to tweak min/max depending on a cron expression. See props.provisionedConcurrentExecutions | ||
- explicit private VPC configuration (see props.network) | ||
- source code path standardization to "[basePath]/[lambdaEventType]/[lambdaName]/index.ts" (can be overwritten by explicit props.entry) | ||
- custom CA support for HTTP calls (NodeJS NODE_EXTRA_CA_CERTS). See props.extraCaPubCert | ||
- option to subscribe an Lambda Arn to the log group related to the Lambda function. See props.logGroupSubscriberLambdaArn | ||
- adds environment STAGE to Lambda. See props.stage | ||
|
||
### Usage | ||
|
||
#### Simple Typescript Lambda Function | ||
|
||
```ts | ||
// instantiate Lambda construct | ||
// this will bundle your ts code using esbuild | ||
const func = new BaseNodeJsFunction(stack, 'test-lambda', { | ||
stage: 'dev', | ||
eventType: EventType.Http | ||
}); | ||
``` | ||
|
||
#### Complex Typescript Lambda Function | ||
|
||
```ts | ||
// this can be reused in various lambda definitions | ||
const globalLambdaConfig = { | ||
eventType: EventType.Http, | ||
runtime: Runtime.NODEJS_18_X, | ||
extraCaPubCert: 'ABCXxxxyz123123123' // add private CA pub certificate to NodeJS | ||
} | ||
|
||
const lambdaConfig: BaseNodeJsProps = { | ||
// merge config with global defaults | ||
...globalLambdaConfig, | ||
sourceMap: true, // add code source map to esbuild and configure Node. This might impose severe performance penauties | ||
provisionedConcurrentExecutions: { | ||
minCapacity: 1, // min instances in auto-scaling of provisioned lambdas | ||
maxCapacity: 5, // max instances in auto-scaling. if empty, the number of provisioned instances will be fixed to "minCapacity" | ||
schedules: [ // for automatically changing min/max on certain hours | ||
{ | ||
minCapacity: 0, | ||
maxCapacity: 2, | ||
schedule: Schedule.cron({ hour: '22' }), | ||
name: 'Lower provisioned instances during the night' | ||
}, | ||
{ | ||
minCapacity: 1, | ||
maxCapacity: 5, | ||
schedule: Schedule.cron({ hour: '7' }), | ||
name: 'Keep at minimum one provisioned instance during the day' | ||
} | ||
] | ||
} | ||
} | ||
|
||
// register an external Lambda to receive all Cloudwatch log events | ||
// created by this Lambda (used to forward logs to Datadog, Splunk etc) | ||
lambdaConfig.logGroupSubscriberLambdaArn = | ||
'arn:aws:lambda:eu-west-1:012345678:function:datadogForwarder'; | ||
|
||
// instantiate Lambda construct | ||
const func = new BaseNodeJsFunction(stack, 'test-lambda', lambdaConfig); | ||
|
||
// add custom network access rules to default security group created for this lambda | ||
func.defaultSecurityGroup.addEgressRule( | ||
Peer.ipv4('10.20.30.40/32'), | ||
Port.tcp(8888), | ||
'Allow lambda to access api X', | ||
); | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
## Construct OpenApiGatewayLambda | ||
|
||
Rest API built from Openapi specs and aws extensions for running on Lambda functions with the following characteristics: | ||
- Uses API Gateway extensions for OpenAPI for connecting api routes to Lambdas (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html) | ||
- Creates an AWS API Gateway along with multiple Lambdas for each route defined in OpenAPI spec | ||
- Uses api operations that supports Zod schemas in definitions (prop.openapiOperations) | ||
- An opiniated set of defaults that can be overwritten in props | ||
|
||
Partialy inspired on https://blog.serverlessadvocate.com/serverless-openapi-amazon-api-gateway-with-the-aws-cdk-part-1-8a90477ebc24 | ||
|
||
AWS labs has a similar construct, but it relies on openapi specs written in yml and deployed to S3 buckets and CustomResources. We want to avoid S3 buckets and CustomResources to keep things faster/simpler and want to write our openapi specs in pure TS for better typing. | ||
|
||
Check https://github.com/awslabs/aws-solutions-constructs/blob/main/source/patterns/%40aws-solutions-constructs/aws-openapigateway-lambda/lib/index.ts | ||
|
||
### Usage | ||
|
||
TODO | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
## Construct WSO2 API | ||
|
||
Creates a new WSO2 API in a WSO2 server based on api definitions and an Openapi document. | ||
|
||
Check type *Wso2ApiProps* for a complete definition of the props for this construct. | ||
|
||
Supported output attributes for this CustomResource in CFN via GetAtt are: | ||
- EndpointUrl: Endpoint URL of this API in WSO2 | ||
- Wso2ApiId: Id of the API in WSO2 | ||
|
||
### Usage | ||
|
||
```ts | ||
const wso2Props: Wso2ApiProps = { | ||
wso2Config: { | ||
baseApiUrl: 'https://mywso2.com', | ||
credentialsSecretId: 'myWso2Creds', | ||
}, | ||
apiDefinition: { | ||
version: 'v1', | ||
type: 'HTTP', | ||
endpointConfig: { | ||
production_endpoints: { | ||
url: 'http://serverabc.com', | ||
}, | ||
endpoint_type: 'http', | ||
}, | ||
context: '/petstore', | ||
name: 'petstore-sample', | ||
gatewayEnvironments: ['public'], | ||
corsConfiguration: { | ||
accessControlAllowOrigins: ['testwebsite.com'], | ||
}, | ||
}, | ||
openapiDocument: mypetstoreOpenapiDoc, | ||
}; | ||
|
||
// instantiate cdk construct | ||
new Wso2Api(scope, `wso2-petstore`, wso2Props); | ||
``` | ||
|
||
See a complete example at [/examples/src/wso2](/examples/src/wso2) | ||
|
||
For this construct, lots of experiences were extracted from [serverless-wso2-apim](https://github.com/ramgrandhi/serverless-wso2-apim). Thanks for the good work, Ram! |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { RemovalPolicy } from 'aws-cdk-lib/core'; | ||
import { BackoffOptions } from 'exponential-backoff'; | ||
|
||
import { LambdaConfig } from '../lambda/types'; | ||
|
||
/** | ||
* Configurations used on the Lambda that receives events | ||
* from Cloudformation to invoke WSO2 server. So if your | ||
* WSO2 is accessible only via an specific network, or needs special rules | ||
* or internal CA certificates, configure it using this property | ||
*/ | ||
export type Wso2LambdaConfig = Pick< | ||
LambdaConfig, | ||
| 'allowOutboundTo' | ||
| 'securityGroups' | ||
| 'extraCaPubCert' | ||
| 'network' | ||
| 'logGroupSubscriberLambdaArn' | ||
| 'logGroupRetention' | ||
| 'logGroupRemovalPolicy' | ||
>; | ||
|
||
export type Wso2BaseProperties = { | ||
/** | ||
* Configurations related to WSO2 APIM host, credentials tenant etc | ||
*/ | ||
wso2Config: Wso2Config; | ||
/** | ||
* If true, during the creation of this CFN Resource, if an API in WSO2 already exists with the same tenant/name/version, it will fail. | ||
* If false, an existing API in WSO2 can be used. This means that an API that wasn't created by this construct can | ||
* be updated or even deleted by this Custom Resource (if 'Retain' is 'DESTROY' for this resource). | ||
* @default true | ||
*/ | ||
failIfExists?: boolean; | ||
/** | ||
* Automatic retry for checks and mutations | ||
* This is a best effort to make the deployment successful even when WSO2 cluster is unstable, | ||
* but if you use long retries your CFN stack might take too long to fail when the WSO2 server | ||
* is unavailable, as it will continue retrying for minutes. | ||
*/ | ||
retryOptions?: RetryOptions; | ||
/** | ||
* Removes or retains API in WSO2 APIM server when this application is removed from CFN | ||
* https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.RemovalPolicy.html | ||
* Defaults to RETAIN, which means that the API will be kept in WSO2 when this resource is deleted in CFN | ||
*/ | ||
removalPolicy?: RemovalPolicy; | ||
/** | ||
* Lambda config for the CustomResource that will be used for running the WSO2 API calls | ||
* By default this Lambda will have access to all networks so it's able to invoke the WSO2 APIs. | ||
* You can add custom CA pub certs (extraCaPubCert) or configure a specific VPC to run it (network) for example. | ||
*/ | ||
customResourceConfig?: Wso2LambdaConfig; | ||
}; | ||
|
||
/** | ||
* Retry options for API requests to WSO2 server | ||
*/ | ||
export type RetryOptions = { | ||
/** | ||
* Retry options for check operations such as getting API to compare with desired contents. | ||
* | ||
* @default "{ startingDelay: 500, timeMultiple: 1.5, numOfAttempts: 10, maxDelay: 10000 }" which means retries on [500ms, 750ms, 1125ms, 1687ms (elapsed: 4s), 2531, 3796, 5696, 8542 (elapsed: 24s), 10000, 10000, 10000, 10000, 10000 (elapsed: 74s max)] | ||
*/ | ||
checkRetries?: BackoffOptions; | ||
/** | ||
* Retry options for operations such as create/update API on WSO2, change api lifecycle, publish Openapi docs etc | ||
* @default "{ startingDelay: 2000, timeMultiple: 1.5, numOfAttempts: 3, maxDelay: 5000 }" | ||
*/ | ||
mutationRetries?: BackoffOptions; | ||
}; | ||
|
||
export type Wso2Config = { | ||
/** | ||
* WSO2 server API base URL. This is the base URL from which the API calls to WSO2 will be sent. | ||
* @example https://mywso2.com/ | ||
*/ | ||
baseApiUrl: string; | ||
/** | ||
* Tenant identification (when using multi tenant setups) | ||
* @example mypublic.com | ||
*/ | ||
tenant?: string; | ||
/** | ||
* Secret id in Secret Manager with credentials for accessing WSO2 API. It will be used for | ||
* listing APIs, creating client credentials, publishing APIs etc | ||
* @example 'wso2/customers/credentials' - with json contents "{ user: 'myuser', pwd: 'mypass' }" | ||
*/ | ||
credentialsSecretId: string; | ||
/** | ||
* Version of the WSO2 server API | ||
* @default v1 | ||
*/ | ||
apiVersion?: 'v1'; | ||
}; |
Oops, something went wrong.