使用LambdaIntegration时,CDK覆盖绑定 [英] CDK override bind when using LambdaIntegration

查看:138
本文介绍了使用LambdaIntegration时,CDK覆盖绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用LambdaIntegration类时,绑定函数会自动向lambda添加权限:

When using LambdaIntegration class the bind function add permission to the lambda automatically:

    bind(method) {
        super.bind(method);
        const principal = new iam.ServicePrincipal('apigateway.amazonaws.com');
        const desc = `${method.restApi.node.uniqueId}.${method.httpMethod}.${method.resource.path.replace(/\//g, '.')}`;
        this.handler.addPermission(`ApiPermission.${desc}`, {
            principal,
            scope: method,
            sourceArn: method.methodArn,
        });
        // add permission to invoke from the console
        if (this.enableTest) {
            this.handler.addPermission(`ApiPermission.Test.${desc}`, {
                principal,
                scope: method,
                sourceArn: method.testMethodArn,
            });
        }
    }

当前,我创建了多个API网关,其中90%的API网关会触发相同的lambda函数,这会导致以下错误:

Currently, I create multiple API Gateways who 90% of them trigger the same lambda function, this causes me the following error :

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

更多信息此处.

我的目标是用我自己的函数覆盖bind函数,并自己处理权限,诸如此类:

My goal is to override the bind function with my own function and handle the permissions by myself, something like that:

arn:aws:execute-api:{AWS_REGION}:{AWS_ACCOUNT}:{API_ID}/*/*/*

我知道这不是最佳做法,但目前这是唯一可行的解​​决方法.

I know this is not a best practice but right now this is the only working workaround.

这是我创建的新类:

    class customLambdaIntegration extends apigateway.LambdaIntegration{
          myHandler: lambda.IFunction;
          constructor(handler: lambda.IFunction, options?: LambdaIntegrationOptions) {
            super(handler, options);
            this.myHandler = handler;
          }
          bind(method: Method) {
            const principal = new iam.ServicePrincipal('apigateway.amazonaws.com');
            const desc = `${method.restApi.node.uniqueId}.${method.httpMethod}.${method.resource.path.replace(/\//g, '.')}`;
            this.myHandler.addPermission(`ApiPermission.${desc}`, {
              principal,
              scope: method,
              sourceArn: method.methodArn.toString().replace(api.deploymentStage.stageName,'*')
            });
          }
        }

运行cdk list时出现此错误:

if (!this.scope) { throw new Error('AwsIntegration must be used in API'); }

引发错误的有问题的代码段:

Problematic piece of code which throw the error:

    class AwsIntegration extends integration_1.Integration {
        constructor(props) {
            const backend = props.subdomain ? `${props.subdomain}.${props.service}` : props.service;
            const type = props.proxy ? integration_1.IntegrationType.AWS_PROXY : integration_1.IntegrationType.AWS;
            const { apiType, apiValue } = util_1.parseAwsApiCall(props.path, props.action, props.actionParameters);
            super({
                type,
                integrationHttpMethod: props.integrationHttpMethod || 'POST',
                uri: cdk.Lazy.stringValue({ produce: () => {
                        if (!this.scope) {
                            throw new Error('AwsIntegration must be used in API');
                        }
                        return cdk.Stack.of(this.scope).formatArn({
                            service: 'apigateway',
                            account: backend,
                            resource: apiType,
                            sep: '/',
                            resourceName: apiValue,
                        });
                    } }),
                options: props.options,
            });
        }
        bind(method) {
            this.scope = method;
        }
    }

LambdaIntegration文档.

任何帮助将不胜感激.

这可能对谁有帮助,我打开了一个功能请求以实现我的功能并手动处理lambda权限:

To whom this might be helpful, I open a feature request to implement my function and manually handle the lambda permission :

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

推荐答案

发现了问题,由于AwsIntegration类实现了this.scope=method,因此绑定函数中缺少this['scope'] = method;.

Found the issue, this['scope'] = method; were missing inside the bind function since AwsIntegration class implements this.scope=method.

完整代码:

       class customLambdaIntegration extends apigateway.LambdaIntegration{
          // myScope : cdk.IConstruct;
          myHandler: lambda.IFunction;
          MyOptinos: apigateway.LambdaIntegrationOptions | undefined;
          constructor(handler: lambda.IFunction, options?: LambdaIntegrationOptions) {
            super(handler, options);
            this.myHandler = handler;
            this.MyOptinos = options;
          }
          bind(method: Method) {
            this['scope'] = method;
            const principal = new iam.ServicePrincipal('apigateway.amazonaws.com');
            const desc = `${method.restApi.node.uniqueId}.${method.httpMethod}.${method.resource.path.replace(/\//g, '.')}`;
            this.myHandler.addPermission(`ApiPermission.${desc}`, {
              principal,
              scope: method,
              sourceArn: method.methodArn.toString().replace(api.deploymentStage.stageName,'*')
            });
        }
      }

这篇关于使用LambdaIntegration时,CDK覆盖绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆