在 AWS CDK 中使用 Lambda.Function.lambda_from_arn 创建带有阶段变量的 API 网关终端节点不起作用

问题描述 投票:0回答:1

我有多个 AWS 堆栈,除其他外,我创建了 AWS Lambda 和 API 网关端点,让我们将此堆栈视为 lambda_unified_crud_stack 和第二个名为 lambda_other_crud_stacklambda_other_crud_stack 首先运行)

当在同一个堆栈中,lambda_unified_crud_stack时,我创建一个 Lambda,并为该 Lamba 创建一个带有阶段变量的 API 网关资源,一切正常,没有任何问题。端点是在集成请求中带有阶段变量的 Lambda 处创建的,类似于

TestLambda:${stageVariables.lambdaAlias}
。我通过使用 CDK 执行以下操作来实现这一目标。

TestLambda = lambda_.Function(
    self,
    "my_lambda",
    function_name="TestLambda",
    description="A Lambda to test permissions",
    code=lambda_code,
    memory_size=512,
    handler="my_lambda.main",
    runtime=lambda_.Runtime.PYTHON_3_9,
    timeout=Duration.minutes(1),
)

#get_gateway() is custom code to the the API

api = get_gateway(self.scope, gateway_name)
root = api.root

lambdaArn = TestLambda.function_arn + ":${stageVariables.lambdaAlias}"
integration = aws_apigateway.LambdaIntegration(lambdaArn)

endpoint = root.resource_for_path("/test_lambda_api/").add_method("GET", integration)

这样做时,我创建了 API 网关资源,其中集成请求是引用阶段变量的 lambda,没有出现任何问题。

但在其他情况下,我需要获取之前在 lambda_other_crud_stack 中创建的 Lamdba,以便在此堆栈中使用,以便我可以为其创建端点,在这种情况下,我会执行以下操作。

other_stack_lambda_arn_ = f"arn:aws:lambda:{self.region}:{self.account_id}:function:OtherStackLambd"
OtherStackLambda=  aws_lambda.Function.from_function_arn(self.scope, id=f"Role{lambda_arn_}", function_arn = other_stack_lambda_arn_ )

#get_gateway() is custom code to the the API

api = get_gateway(self.scope, gateway_name)
root = api.root

other_lambdaArn = OtherStackLambda.function_arn + ":${stageVariables.lambdaAlias}"
other_integration = aws_apigateway.LambdaIntegration(other_lambdaArn)

endpoint = root.resource_for_path("/test_lambda_api/other_lambda").add_method("GET", other_integration )

当我在 CDK 中运行它时,我收到错误:

[#/FunctionName: string [arn:aws:lambda:eu-west-1:668526471736:function:OtherStackLambd:${stageVariables.lambdaAlias}] does not match pattern ^(arn:(aws[a-zA-Z-]*)?:lambda:)?([a-z]{2}((-gov)|(-iso([a-z]?)))?-[a-z]+-\d{1}:)?(\d{12}:)?(function:)?([a-zA-Z0-9-_]+)(:(\$LATEST|[a-zA-Z0-9-_]+))?$]
,当我期望这能像其他情况一样创建端点时。

当我做同样的事情,但不引用阶段变量时(意味着不这样做 other_lambdaArn = OtherStackLambda.function_arn + ":${stageVariables.lambdaAlias}"),使用 aws_lambda.Function.from_function_arn() 可以正常工作。

我在Github上发现了这个问题:https://github.com/aws/aws-cdk/issues/23296,并尝试使用

fromFunctionAttributes()
,而不是`lambda_from_arn(),但仍然不起作用。

一个可能的解决方案是始终在同一个堆栈中创建所有 AWS Lambda 和相关的 API 网关端点,但这行不通,因为根据公司政策,我需要以尽可能最好的方式组织所有内容(对于例如,一个堆栈中与 DynamoDB 相关的所有 AWS Lambda,另一个堆栈中与 Neptune 相关的所有 AWS Lambda)

python aws-lambda aws-api-gateway aws-cdk aws-code-deploy
1个回答
0
投票

更新: 已经开始工作了,现在 CDK 的表现就像我们预期的那样,我们所做的如下:

对于使用在同一堆栈中创建的 Lambda 创建端点资源,我们保持基本相同,只是根据我的需要进行一些细微的更改:

TestLambda = lambda_.Function(
    self,
    "my_lambda",
    function_name="TestLambda",
    description="A Lambda to test permissions",
    code=lambda_code,
    memory_size=512,
    handler="my_lambda.main",
    runtime=lambda_.Runtime.PYTHON_3_9,
    timeout=Duration.minutes(1),
)
#get_gateway() is custom code to the the API

api = get_gateway(self.scope, gateway_name)
root = api.root

lambdaArn = TestLambda.function_arn + ":${stageVariables.lambdaAlias}"
lambda_function =aws_lambda.Function.from_function_arn(self.scope,f'lambda_integration_request_{lambdaArn}' ,lambdaArn)
integration = aws_apigateway.LambdaIntegration(lambda_function, allow_test_invoke=False)

endpoint = root.resource_for_path("/test_lambda_api/").add_method("GET", integration)

但是对于我尝试使用从另一个堆栈创建的 Lambda 来创建 API 网关资源的情况,我会这样做

# The Lambda name in this case is OtherStackLambd
other_stack_lambda_arn_ = f"arn:aws:lambda:{self.region}:{self.account_id}:function:OtherStackLambd"

#get_gateway() is custom code to the the API

api = get_gateway(self.scope, gateway_name)
root = api.root

other_lambdaArn = OtherStackLambda.function_arn + ":${stageVariables.lambdaAlias}"
integration = aws_apigateway.AwsIntegration(
          service='lambda',
          path=f'2015-03-31/functions/{lambdaArn}/invocations',
          region=self.region,
          proxy=True,
         options=aws_apigateway.LambdaIntegrationOptions(allow_test_invoke=False)                     
)
endpoint = root.resource_for_path("/test_lambda_api/other_lambda").add_method("GET", other_integration )

这样做很有效,一切都很好。 但是我不会关闭这个问题,因为在CDK文档中,它特别指出AwsIntegration旨在调用所有AWS服务操作,但不建议用于调用Lambda函数,因为Lambda自定义集成是一项遗留技术。

© www.soinside.com 2019 - 2024. All rights reserved.