pulumi / pulumi-aws-apigateway

Apache License 2.0
11 stars 5 forks source link

API Gateway provisioned concurrency for Lambda functions swagger missing published version #25

Open catmeme opened 2 years ago

catmeme commented 2 years ago

Hello!

Issue details

The URI in the swagger specification that's generated with Crosswalk does not have a version:

https://github.com/pulumi/pulumi-awsx/blob/master/nodejs/awsx/apigateway/api.ts#L861-L862

It’s important to remember that the feature is applied explicitly to a function version or alias. Ensure that your invocation method is calling this alias, and not the $LATEST version. Provisioned Concurrency cannot be applied to the $LATEST version.

https://aws.amazon.com/blogs/compute/creating-low-latency-high-volume-apis-with-provisioned-concurrency/

Patching this by injecting the version corrects the issue for this case:

const uri = pulumi.interpolate
            `arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${lambda.qualifiedArn}/invocations`;

It also looks like we had to patch it here:

https://github.com/pulumi/pulumi-awsx/blob/master/nodejs/awsx/apigateway/api.ts#L677

function: lambda.qualifiedArn,

Steps to reproduce

const lambdaFunctionApi = new aws.lambda.Function(
  `${appName}-api`,
  lambdaFunctionArgs,
);

new aws.lambda.ProvisionedConcurrencyConfig(
  `${appName}-provisioned-concurrency`,
  {
    functionName: lambdaFunctionApi.name,
    qualifier: lambdaFunctionApi.version,
    provisionedConcurrentExecutions: 5,
  },
  { parent: lambdaFunctionApi },
);

const apiApp = new awsx.apigateway.API(
  `${appName}-api`,
  {
    routes: [
      {
        path: "/{proxy+}",
        method: "GET",
        eventHandler: lambdaFunctionApi,
        apiKeyRequired: true,
      },
    ],
  }
  { dependsOn: [lambdaFunctionApi] },
);

Expected: API Gateway routes to my lambda Actual: API Gateway does not route to my lambda because it's missing the version in the URI for the lambda of the swagger spec.

catmeme commented 2 years ago

Our work-around to avoid monkey-patching is to declare the swagger sections explicitly using the data property:

    routes: [
      {
        path: "/",
        method: "ANY",
        data: {
          "x-amazon-apigateway-integration": {
            httpMethod: "POST",
            uri: pulumi.interpolate`arn:aws:apigateway:${awsRegion}:lambda:path/2015-03-31/functions/${lambdaFunctionApi.arn}:${lambdaFunctionApi.version}/invocations`,
            passthroughBehavior: "when_no_match",
            type: "aws_proxy",
          },
        },
        // eventHandler: lambdaFunctionApi,
        apiKeyRequired: true,
      },
    ],

And explicitly add permissions on the lambda for the qualified ARN of the REST API using the qualifier property:

new aws.lambda.Permission(`${appName}-lambda-permission-1`, {
  action: "lambda:InvokeFunction",
  function: lambdaFunctionApi.name,
  principal: "apigateway.amazonaws.com",
  qualifier: lambdaFunctionApi.version,
  sourceArn: pulumi.interpolate`${apiApp.restAPI.executionArn}/*/*/`,
});
catmeme commented 2 years ago

This work-around is not complete, as it is missing a securityDefinitions.api_key section of the swagger specification.

mikhailshilkov commented 2 years ago

@catmeme Thank you for the investigation here. Any chance you could open a PR to fix this?

As a side note, there is a new multi-language component for API gateway in the makings, it would be great if you could give it a try at some point: https://www.pulumi.com/registry/packages/aws-apigateway/

catmeme commented 2 years ago

I can address this specific bug, but I'm not sure what other use cases it could potentially break.

Looks like that package is built on top of @pulumi/awsx which is built on top of @pulumi/aws.

It will exhibit the same bug: https://github.com/pulumi/pulumi-awsx/blob/master/nodejs/awsx/apigateway/api.ts#L645