Git Product home page Git Product logo

aws-simple's Issues

Error on "create" from 3.1.0

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.

Can not clean up without having lambda/s3 artifacts built

When require.resolve is used in the aws-simple config file to define the localPaths 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.

Set S3 DeletionPolicy

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

RestApiCloudWatchRole is not cleaned up with aws-cdk >= 2.38.0

Since 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,
    },
})

Proposal: New configuration format

Herewith I propose a simplified configuration format.

Features:

  • More consistent names
  • Useful defaults (e.g. GZIP compression enabled by default; default Lambda memory size is 128 instead of 3008)
  • Routes as a fundamental concept, instead of S3 and Lambda configurations
  • Certain rules are enforced at API level (e.g. catch-all routes make no sense with Assets routes)
  • Enable CORS at route level
  • Define binary media types at route level (only if set, the route is treated as binary)
  • The app version is optional (not everyone follows the concept of parallel deployments)
  • Names must be assigned for the routes. This makes the resource IDs in AWS much more readable.

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.

Authentication for POST

Using authenticationRequired:true with combination of httpMethod: 'POST' doesn't work. Function is not executed.

Use `ink` for declarative CLI rendering

  • Update aws-simple create
  • Update aws-simple upload
  • Update aws-simple start
  • Update aws-simple list
  • Update aws-simple tag
  • Update aws-simple clean-up
  • Remove cliui/listr/prompts dependencies and types

DEV Server: Document source map support

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?

CORS preflight request returns 500 error

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:

  1. Add a lambda function route with corsEnabled
...
    {
      type: 'function',
      httpMethod: 'POST',
      publicPath: '/hello',
      path: 'dist/hello.js',
      functionName: 'hello',
      corsEnabled: true, // <==
    },
    ....
  1. Send correct 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': '*', // <==
  },
});
  1. Deploy the website to AWS
  2. Call the lambda function path with OPTIONS method e.g.:
 curl <your-domain>/hello -X OPTIONS -v 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.