AWS CDK - 如何在部署之前向API Gateway授予对Lambda的调用权限?

4
这个问题涉及到一个我在这里遇到的问题: AWS CDK如何从OpenApi spec创建由Lambda支持的API网关?
我使用AWS CDK使用OpenAPI规范创建了一个API网关。该API由Lambda支持,并且需要APIG获得调用Lambda的权限。
当我授予APIG调用我的Lambda的权限时:
myLambda.addPermission("PermitAPIGInvocation", Permission.builder()
                                  .action("lambda:InvokeFunction")
                                  .principal(ServicePrincipal.Builder.create("apigateway.amazonaws.com")
                                     .build())
                                  .sourceArn(mySpecRestApi.arnForExecuteApi())
                                  .build());

当我尝试调用API端点时,我会收到一个500错误“Lambda函数权限无效”,直到我重新部署API。在使用APIG控制台测试lambda函数时没有任何问题。

如何让ApiGateway自动工作而无需手动干预?即如何确保我的lambda函数具有必要的权限?


你能展示一下如何在CDK项目中将Lambda附加到API网关吗? - Logemann
没有附件本身,APIG是通过SpecRestApi创建的,在OAS规范的x-amazon-apigateway-integration段中,有一个uri属性指向APIG调用ARN和一个credentials属性,其中包含一个角色,允许调用所有lambda函数。 - John
在使用CDK创建APIGW并将Lambda附加到其中时,据我所知,CDK会为您添加invokeFunction权限。 - Logemann
是的,当您使用 RestApi 时似乎是这种情况,但是当您使用 SpecRestApi 时不是这种情况。 - John
这很奇怪,因为SpecRestApi和RestApi都扩展了RestApiBase。而且我没有在RestApi类中看到任何特殊的权限处理。抱歉,我无法帮助您解决此问题,因为我没有可用的APIGW测试堆栈。 - Logemann
2个回答

8

使用OpenAPI规范配置API网关有些困难。您需要小心设置正确的URI和凭据。此外,凭证似乎无法替换。确保您的Lambda函数和角色也已部署。

对我而言有效的方法是定义角色并在规范中设置以下内容:

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

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

在规范中:

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"

3

不确定您的代码出了什么问题,但在CDKv2中,在此问题修复之后,以下代码片段可以正常工作:

myLambda.addPermission('PermitAPIGInvocation', {
  principal: new ServicePrincipal('apigateway.amazonaws.com'),
  sourceArn: apigw.arnForExecuteApi('*')
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接