3

This question relates to a problem I cam across here: AWS CDK how to create an API Gateway backed by Lambda from OpenApi spec?.

I create an API Gateway using an OpenAPI spec with the AWS CDK. The API is backed by a Lambda and the APIG needs permission to invoke the Lambda.

When I grant permission to APIG to call my lambda:

myLambda.addPermission("PermitAPIGInvocation", Permission.builder()
                                  .action("lambda:InvokeFunction")
                                  .principal(ServicePrincipal.Builder.create("apigateway.amazonaws.com")
                                     .build())
                                  .sourceArn(mySpecRestApi.arnForExecuteApi())
                                  .build());

then I get a 500 error "Invalid permissions on Lambda function" when I try to call the API endpoint until I have redeployed the API. There is no issue when I test the lambda using the APIG console.

How can I have the ApiGateway automatically work without manual intervention? i.e. how do I ensure my lambda has the necessary permission?

John
  • 10,837
  • 17
  • 78
  • 141
  • can you show how you attach the lambda to the apigw in your CDK project? – Logemann Jun 06 '20 at 18:28
  • There's no attachment per se, the APIG is created via `SpecRestApi`, and within the OAS spec's `x-amazon-apigateway-integration` stanza there is `uri` property pointing at the APIG invocations ARN and a `credentials` property with a role that allows invocation of all lambdas. – John Jun 09 '20 at 11:50
  • when creating the APIGW with CDK and attaching a lambda to it... to my knowledge CDK does the invokeFunction permission addition for you. – Logemann Jun 09 '20 at 13:02
  • Yes, that seems to be the case when you use `RestApi`, but not when you use `SpecRestApi`. – John Jun 09 '20 at 13:11
  • which would be weird because SpecRestApi as well as RestApi extends RestApiBase. And i dont see any special permission handling in RestApi class. Sorry. Cant help you on this one because i have no APIGW test stack available. – Logemann Jun 09 '20 at 23:04

2 Answers2

7

It's kind of difficult to configure the API Gateway with the OpenAPI spec. You really need to be cautious to set the correct URI and credentials. Furthermore, credentials seem incapable of substitution. Make sure that your lambda and role is deployed too.

What worked for me was defining the role and set the following in the spec:

const apiRole = new Role(scope, 'apiRole', {
  roleName: 'apiRole',
  assumedBy: new ServicePrincipal('apigateway.amazonaws.com'),
});

apiRole.addToPolicy(new PolicyStatement({
  resources: ['*'],
  actions: ['lambda:InvokeFunction'] }));

and in the spec:

x-amazon-apigateway-integration:
    uri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:optionsApi/invocations"
    passthroughBehavior: "when_no_match"
    httpMethod: "POST"
    type: "aws_proxy"
    credentials: "arn:aws:iam::111111122222:role/apiRole"
w.brian
  • 16,296
  • 14
  • 69
  • 118
2

Not sure what was wrong with your code, but in CDKv2 after this issue fix the following snippet works:

myLambda.addPermission('PermitAPIGInvocation', {
  principal: new ServicePrincipal('apigateway.amazonaws.com'),
  sourceArn: apigw.arnForExecuteApi('*')
});
astef
  • 8,575
  • 4
  • 56
  • 95