aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.66k stars 3.92k forks source link

aws_apigateway: apigateway.LambdaIntegration Integration timeout must be between 50 milliseconds and 29 seconds. #31063

Closed schaetay closed 2 months ago

schaetay commented 3 months ago

Describe the bug

The default integration for API Gateway is 29 seconds. After requesting an increase for the account/region I am unable to update the lambda integration timeout beyond the default 29 second timeout via the CDK however I am able to update the timeout beyond the default in the AWS Console.

Expected Behavior

The Lambda integration timeout should be updated to the specified value beyond the default 29 seconds when deploying via CDK.

Current Behavior

The Lambda integration timeout remains at the default 29-second limit even after deployment, despite the requested increase being successfully applied in the AWS Console.

Reproduction Steps

const api = new apigateway.RestApi(this, 'api', {
  restApiName: 'api',
  deploy: true,
  endpointConfiguration: {
    types: [ apigateway.EndpointType.REGIONAL ]
  },
});

const fn = new PythonFunction(this, 'fn', {
  functionName: 'lambda-function',
  entry: '../dir/lambda',
  runtime: lambda.Runtime.PYTHON_3_11,
  timeout: cdk.Duration.minutes(2),
});

new apigateway.LambdaIntegration(fn, {
  requestTemplates: { "application/json": '{ "statusCode": "200" }' },
  timeout: cdk.Duration.seconds(31)
});

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.151.0 (build b8289e2)

Framework Version

No response

Node.js Version

v18.18.0

OS

Windows 11 Version 23H2

Language

TypeScript

Language Version

TypeScript 5.3.3

Other information

No response

pahud commented 3 months ago

Yes according to this, we probably should unblock the limitation https://aws.amazon.com/about-aws/whats-new/2024/06/amazon-api-gateway-integration-timeout-limit-29-seconds/

https://github.com/aws/aws-cdk/blob/79b5cd2390508e7b5c3d5c93001e30387bf88a4e/packages/aws-cdk-lib/aws-apigateway/lib/integration.ts#L83-L95

and

https://github.com/aws/aws-cdk/blob/79b5cd2390508e7b5c3d5c93001e30387bf88a4e/packages/aws-cdk-lib/aws-apigatewayv2/lib/http/integration.ts#L260-L262

As there's no way to work it around, I am making it a p1 and we welcome pull requests.

godwingrs22 commented 2 months ago

Hi @schaetay, I tried to reproduce the bug with the following code in cdk v2.151.0 but I was able to synth and deploy successfully after increasing the limit in my account/region. Based on checking further, seems this issue is already addressed in this PR #30547. It is available from CDK #v2.147.0.

 // Define the Lambda function with inline code
    const lambdaFunction = new lambda.Function(this, 'MyLambdaFunction', {
      runtime: lambda.Runtime.NODEJS_18_X, // Choose your Lambda runtime
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          console.log('Received event:', JSON.stringify(event, null, 2));
          return {
            statusCode: 200,
            body: JSON.stringify({ message: 'Hello, World!' }),
          };
        };
      `),
    });

    // Define the API Gateway
    const api = new apigateway.RestApi(this, 'MyApi', {
      restApiName: 'MyService',
      description: 'This service serves Lambda functions.',
      deploy: true,
      endpointConfiguration: {
        types: [apigateway.EndpointType.REGIONAL]
      },
    });

    // Create a new Lambda integration
    const lambdaIntegration = new apigateway.LambdaIntegration(lambdaFunction, { timeout: cdk.Duration.seconds(31) });

    // Create a new resource and method
    api.root.addMethod('GET', lambdaIntegration);

image

Could you please let us know which CDK version are you using as there is possibility if the version < v2.147.0, then you might get a validation error during synth or deploy

pahud commented 2 months ago

Thank you @godwingrs22 I will look into this issue again.

github-actions[bot] commented 2 months ago

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

pahud commented 2 months ago

Hi @godwingrs22

I tried again and yes I can reproduce this with 2.151.0

export class DummyStack2 extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const api = new apigateway.RestApi(this, 'api', {
      restApiName: 'api',
      deploy: true,
      endpointConfiguration: {
        types: [ apigateway.EndpointType.REGIONAL ]
      },
    });

    // dummy function
    const fn = new lambda.Function(this, 'dummy-function', {
      code: lambda.Code.fromInline('dummy'),
      runtime: lambda.Runtime.NODEJS_LATEST,
      handler: 'index.handler',
    })

    const lambdaIntegration = new apigateway.LambdaIntegration(fn, {
      timeout: cdk.Duration.seconds(31)
    });

    api.root.addMethod('GET', lambdaIntegration); 

  }
}

dummy-stack2: creating CloudFormation changeset... 4:34:37 PM | CREATE_FAILED | AWS::ApiGateway::Method | apiGETECF0BD67 Resource handler returned message: "Timeout should be between 50 ms and 29000 ms (Service: ApiGateway, Status Code: 400, Request ID: 1a9107c3-3c62-4e05 -9f0c-80f6174b1285)" (RequestToken: 4921f340-9655-87e0-6eee-5bad38b11a1b, HandlerErrorCode: InvalidRequest)

cdk synth is actually good but cloudformation would return error.

I see this on cdk synth

 Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        IntegrationHttpMethod: POST
        TimeoutInMillis: 31000 <-----HERE
        Type: AWS_PROXY
        Uri:
          Fn::Join:
            - ""
            - - arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/
              - Fn::GetAtt:
                  - dummyfunction8EE12489
                  - Arn
              - /invocations
      ResourceId:
        Fn::GetAtt:
          - apiC8550315
          - RootResourceId
      RestApiId:
        Ref: apiC8550315

Per doc:

TimeoutInMillis Custom timeout between 50 and 29,000 milliseconds. The default value is 29,000 milliseconds or 29 seconds.

I think the limitation is on CFN and CDK should catch that on synth.

% npx cdk --version 2.151.0 (build b8289e2) % grep aws-cdk-lib package.json "aws-cdk-lib": "2.151.0",

pahud commented 2 months ago

According to this, it's actually a soft limit which defaults to 29 seconds.

https://github.com/aws/aws-cdk/blob/9acd5288b2b9a4d72dac199d472a42b5590a916e/packages/aws-cdk-lib/aws-apigateway/lib/integration.ts#L83-L95

And for REST API the value can be raised

  • You can't set the integration timeout to less than 50 milliseconds. You can raise the integration timeout to greater than 29 seconds for Regional APIs and private APIs, but this might require a reduction in your account-level throttle quota limit.

That explains why CDK is not blocking that and just pass the value straight to CFN.

pahud commented 2 months ago

@schaetay

After requesting an increase for the account/region I am unable to update the lambda integration timeout beyond the default 29 second timeout via the CDK however I am able to update the timeout beyond the default in the AWS Console.

  1. So you have escalated this limit to a number greater to 29 seconds.
  2. You can update that from console but you can't do that with CDK.

Questions:

  1. Can you share the full error message you have seen when you update it using CDK?
  2. Are you able to tell is the error from CDK or cloudformation?
github-actions[bot] commented 2 months ago

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

bbcbreno commented 2 months ago

I was using cdk 2.141.0, after updates cdk to 2.155.0 worked for me. Thanks @godwingrs22