简体   繁体   English

aws-cdk LambdaRestApi:最终策略大小大于限制

[英]aws-cdk LambdaRestApi: The final policy size is bigger than the limit

Hi i have been trying many possibilities, but now i would need some help.嗨,我一直在尝试很多可能性,但现在我需要一些帮助。

I am using aws-cdk to create architecture by code and so far things have going well.我正在使用 aws-cdk 通过代码创建架构,到目前为止一切进展顺利。 Now i am running into this issue:现在我遇到了这个问题:

The final policy size is bigger than the limit (20480)

In understand what it means, but i have no idea how to solve it.了解它的含义,但我不知道如何解决它。

I am creating a lambdafunction to handle all requests:我正在创建一个 lambda 函数来处理所有请求:

const router = new lambda.Function(this, apiName + '-handler-temp', {
      runtime: LambdaRuntime, // execution environment
      code: lambda.Code.fromAsset('bin/lambda'), // code loaded from "lambda" directory
      handler: 'index.handler', // file is "index", function is "handler"
      vpc: vpc,
      environment: {
        DB_HOST: props?.rdsEndpoint as string,
        DB_USER: props?.rdsDbUser as string,
        DB_PASS: props?.rdsDBPass as string,
        DB_PORT: props?.rdsPort as string,
        DB_DIALECT: props?.rdsDbSchema as string,
        DB_DATABASE: props?.rdsDBName as string,
      },
      layers: [layer],
      timeout: Duration.seconds(30),
      memorySize: 1024,
    })

and the LambdaRestApi is defined like this: LambdaRestApi 的定义如下:

const api = new LambdaRestApi(this, apiName, {
      handler: router,
      proxy: false,
      cloudWatchRole: false,
      description: 'API for Backend',
      deployOptions: {
        stageName: 'prod',
      },
      domainName: domainProperties,
    })

I am creating Endpoints where i am using 23 times addMethod .我正在创建使用 23 次addMethod的端点。

eg例如


const user = api.root.addResource('user')
user.addMethod(HttpMethod.POST)
user.addMethod(HttpMethod.GET)
user.addMethod(HttpMethod.PATCH)

since only one lambda is used to be invoked from apigateway, i am curious, how i can get control of only one policy to be used for lambda execution and it is not creating a new one every time.因为只有一个 lambda 用于从 apigateway 调用,所以我很好奇,我如何才能控制仅用于 lambda 执行的一个策略,并且它不会每次都创建一个新策略。

I also tried to add property role: role to the lambda function with this role definition:我还尝试使用此角色定义将属性role: role添加到 lambda 函数:

const role = new Role(this, apiName + 'ApiGWPermissions', {
      assumedBy: new ServicePrincipal('apigateway.amazonaws.com'),
    })

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

but then i am running into different errors.但后来我遇到了不同的错误。

Has someone solved this riddle?有人解开了这个谜语吗?

Cheers干杯

As suggested in the CDK issue which Ian Walters mentioned, stripping the generated method permissions solved this for me.正如 Ian Walters 提到的CDK 问题中所建议的那样,剥离生成的方法权限为我解决了这个问题。 I'm using .Net but I'd expect that the approach should work for all language implementations.我正在使用.Net,但我希望该方法适用于所有语言实现。 This function removes the permissions:此函数删除权限:

public void StripMethodPermissions(ConstructNode node) {
    foreach (var child in node.Children) {
        if (child is Amazon.CDK.AWS.APIGateway.Method) {
            var method = ((Amazon.CDK.AWS.APIGateway.Method)child);
            var permissions = method.Node.Children.Where(c => c is Amazon.CDK.AWS.Lambda.CfnPermission);
            foreach (var permission in permissions) {
                child.Node.TryRemoveChild(permission.Node.Id);
            }
        }
        if (child.Node.Children.Length > 0) StripMethodPermissions(child.Node);
    }
}

I'm using the technique like this:我正在使用这样的技术:

var api = new RestApi(this, "MyRestApi", new RestApiProps {
    RestApiName = "MyRestApiV1"
});

var handlerLambda = new Function(this, "RequestHandler", new FunctionProps {
    Runtime = Runtime.DOTNET_CORE_3_1,
    ...
});

// Add resources and methods which use the handlerLambda here

// Remove all generated permissions
StripMethodPermissions(api.Root.Node);

// Add a single invoke permission for the lambda
handlerLambda.GrantInvoke(new ServicePrincipal("apigateway.amazonaws.com"));

Thanks to nija-at for showing the way感谢nija-at为您指明方向

@Elliveny has the correct answer. @Elliveny 有正确的答案。 Here is a code snitbit for Python which does the same thing (as I cannot post formatted code in comments):这是 Python 的代码 snitbit,它做同样的事情(因为我不能在评论中发布格式化的代码):

from aws_cdk import (
    aws_lambda as _lambda,
    aws_events as events,
    aws_iam as iam,
    core,
)

for child in self.node.children:
    if isinstance(child, events.Rule):
        for eventChild in child.node.children:
            if isinstance(eventChild, _lambda.CfnPermission):
                child.node.try_remove_child(eventChild.node.id)

Remember that if you do this, you still need to grant invoke on your lambda for the "events.amazonaws.com" ServicePrincipal.请记住,如果您这样做,您仍然需要在您的 lambda 上为“events.amazonaws.com”ServicePrincipal 授予调用权限。 Something like:就像是:

my_lambda.add_permission(
    "RuleInvoke",
    principal=iam.ServicePrincipal("events.amazonaws.com"),
    action="lambda:InvokeFunction",
    source_arn=f"arn:aws:events:{core.Aws.REGION}:{core.Aws.ACCOUNT_ID}:rule/your-rule-name-here*",
)

I hit a similar issue.我遇到了类似的问题。 There is a CDK issue that might help resolve it if addressed,有一个 CDK 问题,如果得到解决,可能有助于解决它,

https://github.com/aws/aws-cdk/issues/9327 https://github.com/aws/aws-cdk/issues/9327

Its also worth noting that by default lambda integrations have allowTestInvoke set to true, which pretty much is going to double the policy document size.还值得注意的是,默认情况下 lambda 集成将allowTestInvoke设置为 true,这几乎会使策略文档大小翻倍。

I'm not sure if you can alter the integration options for the lambda with LambdaRestApi though, I'm using RestApi directly.我不确定您是否可以使用LambdaRestApi更改 lambda 的集成选项,但我直接使用RestApi

A short term fix might be to use RestApi rather than LambdaRestApi and create the lambda integration directly with the allowTestInvoke option set to false.短期修复可能是使用RestApi而不是LambdaRestApi ,并在将allowTestInvoke选项设置为 false 的情况下直接创建 lambda 集成。

The other thing I did that helped was to just create more than one lambda that worked the same way, but got attached to different routes (eg same code, permissions etc, just different logical id) to also reduce the policy document size a bit.我做的另一件事是创建多个以相同方式工作的 lambda,但附加到不同的路由(例如,相同的代码、权限等,只是不同的逻辑 id)也可以稍微减小策略文档的大小。

I'm a bit pressed for development time hence the work-arounds.我有点急于开发时间,因此需要解决方法。 Personally, I think the right solution would be to fix it in the CDK and propose a PR such that LambdaRestApi just did what the user would expect, wild-card permission for the lambda for all就个人而言,我认为正确的解决方案是在 CDK 中修复它并提出一个 PR,这样 LambdaRestApi 就可以满足用户的期望,对所有人的 lambda 通配符许可

You can increase the memory size of lambda by doing this您可以通过这样做来增加 lambda 的内存大小

    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/promoCodes/
      Role: !GetAtt FunctionRole.Arn
      Handler: promoCodesListCsvPDF.promoCodesListCsvPDF
      Policies:
        - AWSLambdaExecute # Managed Policy
        - AWSLambdaBasicExecutionRole # Managed Policy
      MemorySize: 512
      Layers:
        - !Ref NodeDependenciesLayer
      Events:
        promoCodesListCsvPDFEvent:
          Type: Api
          Properties:
            Path: /api/promo-codes/csv-pdf
            Method: POST

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM