clebert / aws-simple Goto Github PK
View Code? Open in Web Editor NEWProduction-ready AWS website deployment with minimal configuration.
License: MIT License
Production-ready AWS website deployment with minimal configuration.
License: MIT License
When enabling CORS for a specific route by setting corsEnabled: true
and calling the corresponding route with the OPTIONS method the ApiGatway returns a 500 error containing the following body:
{
"message": "Internal server error"
}
CloudWatch logs for one request:
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) Starting execution for request: 8d4136c9-be2e-4eec-bd8f-479cdd8ece6a
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) HTTP Method: OPTIONS, Resource Path: /bff
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) Method request path: {}
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) Method request query string: {}
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) Method request headers: {Accept=*/*, Cache-Control=no-cache, X-Forwarded-Proto=https, X-Forwarded-For=XXX, Host=XXXX, Accept-Encoding=gzip, deflate, br, X-Forwarded-Port=443, X-Amzn-Trace-Id=Root=XXX}
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) Method request body before transformations: [Binary Data]
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) Execution failed due to configuration error: Unable to transform request
(8d4136c9-be2e-4eec-bd8f-479cdd8ece6a) Method completed with status: 500
After a bit of investigation it seems like setting the generic binaryMediaType: */*
and the CORS preflight don't work well together (stackoverflow & similar issue in serverless ).
When removing the binaryMediaTypes option from the ApiGateway settings the request works (both preflight and the actual POST request).
To reproduce
Steps to reproduce the behavior:
...
{
type: 'function',
httpMethod: 'POST',
publicPath: '/hello',
path: 'dist/hello.js',
functionName: 'hello',
corsEnabled: true, // <==
},
....
access-control-allow-origin
header in the lambda// dist/hello.js
exports.handler = async () => ({
statusCode: 200,
body: JSON.stringify({hello: 'world'}),
headers: {
'access-control-allow-origin': '*', // <==
},
});
curl <your-domain>/hello -X OPTIONS -v
Is it possible to set the S3 DeletionPolicy to delete ("DeletionPolicy" : "Delete") using the aws-simple.config ? I did not find it on the documentation
Requirement: The IDs should be unique but nevertheless short and readable.
The logical ID must be alphanumeric (A-Za-z0-9) and unique within the template.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html
aws-simple/src/express/utils/create-lambda-request-handler.ts
Lines 30 to 34 in 1f6a177
@robrat I have created a ticket regarding our discussion about code coverage: #107 (comment)
Encountered following error when working with aws-simple :
aws-simple--dealer-search--eeee7170: creating CloudFormation changeset...
โ aws-simple--dealer-search--eeee7170 failed: Error [ValidationError]: Template may not exceed 460800 bytes in size.
at Request.extractError (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/protocol/query.js:50:29)
at Request.callListeners (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/home/runner/work/dealer-search/dealer-search/node_modules/aws-cdk/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'ValidationError',
time: 2020-05-27T09:17:59.184Z,
requestId: 'd2b2659f-d319-4aff-9d19-2db5ea8f3687',
statusCode: 400,
retryable: false,
retryDelay: 173.8271312125218
}
Template may not exceed 460800 bytes in size.
This happen when we tried to update to latest version of [email protected] and [email protected] . When using aws-cdk lower than 1.41 the error was:
Cloud assembly schema version mismatch: Maximum schema version supported is 3.0.0, but found 4.0.0.
Successfully uploaded file: https://bookmark.wtf/{proxy+}
aws-simple create
aws-simple upload
aws-simple start
aws-simple list
aws-simple tag
aws-simple clean-up
cliui
/listr
/prompts
dependencies and typesSince Version 2.38.0 AWS cdk adds the RemovalPolicy "Retain" to the CloudwatchRole which is created automatically for RestApi's. This results in the CloudWatchRole leaking after the Stack was deleted. Therefor more and more IAM Roles are added in our AWS.
The issue was that the RestAPI CloudWatchRole was overwriting the AccountLevel Role for RestAPI's.
Reading from the ApiGateway Doc's, i think aws-simple shouldn't create a new Log Role for every Stack
Note: there can only be a single apigateway.CfnAccount per AWS environment so if you create multiple RestApis with cloudWatchRole=true each new RestApi will overwrite the CfnAccount. It is recommended to set cloudWatchRole=false (the default behavior if @aws-cdk/aws-apigateway:disableCloudWatchRole is enabled) and only create a single CloudWatch role and account per environment.
A solution would be enabling the FeatureFlag @aws-cdk/aws-apigateway:disableCloudWatchRole to prevent the creation of the CloudWatch role by default.
new App({
context: {
'@aws-cdk/aws-apigateway:disableCloudWatchRole': true,
},
})
New usage:
aws-simple tag --add release --remove prerelease --stack-name stage
Using authenticationRequired:true
with combination of httpMethod: 'POST'
doesn't work. Function is not executed.
serverProcess.kill();
See: https://stackoverflow.com/questions/43613456/how-to-really-kill-a-child-process-nodejs
With this command source map support can be enabled for the DEV server:
node -r source-map-support/register $(yarn bin)/aws-simple start
Do you think this should be added to the README?
Usage:
aws-simple stack-termination-protection --enable
aws-simple stack-termination-protection --disable
aws-cdk-lib.aws_apigateway.RestApiProps#minimumCompressionSize is deprecated.
minCompressionSize
When require.resolve
is used in the aws-simple
config file to define the localPath
s for the lambda and s3 integrations, the clean-up
command can not be executed unless the lambda/s3 code has been built before.
Quickly looking through the code, it seems that the local paths are not needed for the clean-up command. Therefore I propose to lazily evaluate them for the other commands where they are needed, e.g. by changing localPath: string
to getLocalPath: () => string
.
Herewith I propose a simplified configuration format.
Features:
Example Config (new):
exports.default = {
appName: 'example',
customDomain: {
certificateArn: 'arn:aws:acm:...',
hostedZoneId: '...',
hostedZoneName: 'example.com',
},
routes: () => ({
'/': {
kind: 'file',
filename: 'dist/main.html',
catchAll: true,
},
'/assets/scripts': {
kind: 'folder',
dirname: 'dist/scripts',
cacheControl: 'max-age=157680000',
},
'/assets/images': {
kind: 'folder',
dirname: 'dist/images',
binaryMediaTypes: ['image/gif'],
cacheControl: 'max-age=157680000',
},
'/api/authorize': {
kind: 'function',
filename: 'dist/api/authorize.js',
parameters: {sessionId: {required: true}},
environment: {CLIENT_ID: '...'},
},
'/api/redirect': {
kind: 'function',
filename: 'dist/api/redirect.js',
parameters: {code: {required: true}, state: {required: true}},
environment: {CLIENT_ID: '...', CLIENT_SECRET: '...'},
},
}),
};
Example Config (old):
exports.default = {
appName: 'example',
appVersion: 'latest',
createStackConfig: () => ({
customDomainConfig: {
certificateArn: 'arn:aws:acm:...',
hostedZoneId: '...',
hostedZoneName: 'example.com',
},
binaryMediaTypes: ['image/gif'],
minimumCompressionSizeInBytes: 1000,
lambdaConfigs: [
{
httpMethod: 'GET',
publicPath: `/api/authorize`,
localPath: 'dist/api/authorize.js',
memorySize: 128,
acceptedParameters: {sessionId: {required: true}},
environment: {CLIENT_ID: '...'},
},
{
httpMethod: 'GET',
publicPath: `/api/redirect`,
localPath: 'dist/api/redirect.js',
memorySize: 128,
acceptedParameters: {code: {required: true}, state: {required: true}},
environment: {CLIENT_ID: '...', CLIENT_SECRET: '...'},
},
],
s3Configs: [
{
type: 'file',
publicPath: '/',
localPath: 'dist/main.html',
bucketPath: 'main.html',
},
{
type: 'file',
publicPath: '/{proxy+}',
localPath: 'dist/main.html',
bucketPath: 'main.html',
},
{
type: 'folder',
publicPath: '/assets/scripts',
localPath: 'dist/scripts',
responseHeaders: {cacheControl: 'max-age=157680000'},
},
{
type: 'folder',
binary: true,
publicPath: '/assets/images',
localPath: 'dist/images',
responseHeaders: {cacheControl: 'max-age=157680000'},
},
],
}),
};
Type definitions:
export interface App {
readonly appName: string;
readonly appVersion?: string;
readonly customDomain?: CustomDomain;
readonly authentication?: Authentication;
readonly disableCompression?: boolean;
readonly routes: (port?: number) => Routes;
}
export interface CustomDomain {
readonly certificateArn: string;
readonly hostedZoneId: string;
readonly hostedZoneName: string;
readonly aliasRecordName?: string;
}
export interface Authentication {
readonly username: string;
readonly password: string;
readonly cacheTtlInSeconds?: number;
}
export interface Routes {
readonly [path: string]: Route;
}
export type Route = FunctionRoute | FileRoute | FolderRoute;
export interface CommonRoute {
readonly routeName?: string;
readonly cacheTtlInSeconds?: number;
readonly enableAuthentication?: boolean;
readonly enableCors?: boolean;
}
export interface FunctionRoute extends CommonRoute {
readonly kind: 'function';
readonly filename: string;
readonly catchAll?: boolean;
readonly method?: FunctionMethod;
readonly handler?: string;
readonly memorySize?: number;
readonly timeoutInSeconds?: number;
readonly loggingLevel?: FunctionLoggingLevel;
readonly parameters?: Readonly<Record<string, FunctionParameterOptions>>;
readonly environment?: Readonly<Record<string, string>>;
}
export type FunctionMethod =
| 'DELETE'
| 'GET'
| 'HEAD'
| 'OPTIONS'
| 'PATCH'
| 'POST'
| 'PUT';
export type FunctionLoggingLevel = 'OFF' | 'ERROR' | 'INFO';
export interface FunctionParameterOptions {
readonly cached?: boolean;
readonly required?: boolean;
}
export interface FileRoute extends CommonRoute {
readonly kind: 'file';
readonly filename: string;
readonly catchAll?: boolean;
readonly binaryMediaType?: string;
readonly cacheControl?: string;
}
export interface FolderRoute extends CommonRoute {
readonly kind: 'folder';
readonly dirname: string;
readonly binaryMediaTypes?: readonly [string, ...string[]];
readonly cacheControl?: string;
}
Disclaimer: In a transition period both variants (new and old) would be supported.
Dev server could be enhanced to support POST data for docker-lambda
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.