使用LambdaIntegration
类时,绑定函数会自动向lambda添加权限:
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函数,这会导致以下错误:
The final policy size (XXX) is bigger than the limit (20480)
更多信息here。
我的目标是用我自己的函数覆盖bind函数并自己处理权限,如下所示:
arn:aws:execute-api:{AWS_REGION}:{AWS_ACCOUNT}:{API_ID}/*/*/*
我知道这不是最佳做法,但是现在这是唯一可行的解决方法。
这是我创建的新类:
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'); }
有问题的代码引发错误:
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 documentation.
任何帮助都感激不尽。
对于谁可能会有帮助,我打开一个功能请求以实现我的功能并手动处理lambda权限:
https://github.com/aws/aws-cdk/issues/5774
最佳答案
发现了问题,因为this['scope'] = method;
类实现了AwsIntegration
,所以绑定函数中缺少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,'*')
});
}
}
关于amazon-web-services - 使用LambdaIntegration时,CDK覆盖绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59713522/