如何通过CDK为导入的Lambda配置预置并发?
问题
需要为某个Lambda函数添加预置并发,但只能通过低层级的CfnFunction资源或通过ARN导入的FunctionProxy访问该Lambda,无法直接访问CDK栈中的高阶Function构造(该构造通常可提供配置预置并发所需的属性和方法)。
详细情况
- CDK栈包含以Lambda为请求处理程序的APIGateway REST API;
- 该Lambda无Alias或Version,使用默认的
$LATEST版本; - APIGateway和Lambda通过cdk-chalice创建,未直接在主栈中定义;
- 二者来自预生成的CloudFormation模板,随后被纳入主CDK栈;
- 无法直接访问APIGateway或Lambda的高阶构造;
- 仅能通过导入Chalice模板获取低层级CfnFunction权限,或通过
lambda.from_function_arn()导入Lambda。
疑问
是否有办法添加预置并发?具体包括:
- 是否可通过修改cdk-chalice预生成的CloudFormation模板实现?
- 是否可通过
lambda.from_function_arn()导入Lambda后,添加Version和ScalableTarget? - 是否有技巧可通过低层级构造CfnFunction添加Version?
- 是否可通过AwsSdkCall生成Lambda的Version并结合AwsCustomResource添加预置并发?
已尝试方案
导入Lambda
# 伪代码 handler = lambda.from_function_arn("arn-from-cdk-chalice-function") # 方案a - CDK部署报错:BaseFunctionImportProxy_不存在current_version属性 handler_version = handler.current_version # 方案b - CDK部署报错:Application Autoscaling无法作用于$LATEST版本 handler_version = handler.latest_version target = appscaling.ScalableTarget(self, "ScalableTarget", service_namespace=appscaling.ServiceNamespace.LAMBDA, max_capacity=100, min_capacity=10, resource_id=f"function:{handler.functionName}:{handler_version.version}", scalable_dimension="lambda:function:ProvisionedConcurrency" )
解决方案
1. 修改cdk-chalice预生成的CloudFormation模板
可以直接修改Chalice输出的CloudFormation模板,添加版本和预置并发配置:
- 找到模板中的
AWS::Lambda::Function资源,新增AWS::Lambda::Version资源并依赖该函数:MyLambdaVersion: Type: AWS::Lambda::Version Properties: FunctionName: !Ref MyChaliceLambdaFunction Description: Version for provisioned concurrency - 接着添加
AWS::ApplicationAutoScaling::ScalableTarget和AWS::ApplicationAutoScaling::ScalingPolicy资源,绑定到上述版本; - 注意:修改后的模板建议作为独立文件纳入CDK栈,避免后续Chalice重新生成模板时覆盖更改。
2. 通过lambda.from_function_arn()导入后添加版本和可扩展目标
导入的FunctionProxy无高阶版本属性,但可手动创建低层级CfnVersion资源生成版本:
from aws_cdk import aws_lambda as lambda_, aws_applicationautoscaling as appscaling # 导入Lambda函数 handler = lambda_.Function.from_function_arn(self, "ImportedLambda", "arn-from-cdk-chalice-function") # 创建Lambda版本 lambda_version = lambda_.CfnVersion(self, "LambdaVersion", function_name=handler.function_name ) # 创建可扩展目标 scalable_target = appscaling.ScalableTarget(self, "LambdaScalableTarget", service_namespace=appscaling.ServiceNamespace.LAMBDA, resource_id=f"function:{handler.function_name}:{lambda_version.attr_version}", scalable_dimension="lambda:function:ProvisionedConcurrency", min_capacity=10, max_capacity=100 ) # 可选:添加缩放策略 scalable_target.scale_to_track_metric("TrackConcurrency", target_value=0.7, predefined_metric=appscaling.PredefinedMetric.LAMBDA_PROVISIONED_CONCURRENCY_UTILIZATION )
核心是用CfnVersion关联导入函数的名称,通过attr_version获取生成的版本号,用于构造可扩展目标的resource_id。
3. 通过低层级CfnFunction添加Version
若已持有CfnFunction实例,可直接创建CfnVersion资源:
# 假设已获取CfnFunction实例 chalice_lambda = CfnFunction.from_cfn_resource(self, "ChaliceLambda", existing_cfn_resource) # 创建版本 lambda_version = lambda_.CfnVersion(self, "LambdaVersion", function_name=chalice_lambda.ref ) # 可扩展目标配置与上述一致
chalice_lambda.ref返回函数逻辑名称,CfnVersion会自动关联到函数当前部署版本。
4. 通过AwsCustomResource结合AwsSdkCall生成版本并配置预置并发
若前序方法受限,可通过AwsCustomResource调用Lambda API完成操作:
from aws_cdk import custom_resources as cr, aws_iam as iam # 导入Lambda函数 handler = lambda_.Function.from_function_arn(self, "ImportedLambda", "arn-from-cdk-chalice-function") # 创建版本的SDK调用 create_version = cr.AwsSdkCall( service="Lambda", action="publishVersion", parameters={"FunctionName": handler.function_name}, physical_resource_id=cr.PhysicalResourceId.from_response("Version") ) # 配置预置并发的SDK调用 put_provisioned_concurrency = cr.AwsSdkCall( service="Lambda", action="putProvisionedConcurrencyConfig", parameters={ "FunctionName": handler.function_name, "Qualifier": create_version.get_response_field("Version"), "ProvisionedConcurrentExecutions": 10 } ) # 创建自定义资源 cr.AwsCustomResource(self, "LambdaProvisionedConcurrency", on_create=[create_version, put_provisioned_concurrency], on_update=[put_provisioned_concurrency], policy=cr.AwsCustomResourcePolicy.from_statements([ iam.PolicyStatement( actions=["lambda:PublishVersion", "lambda:PutProvisionedConcurrencyConfig"], resources=[handler.function_arn, f"{handler.function_arn}:*"] ) ]) )
此方式需配置对应IAM权限,同时注意资源更新时的逻辑处理(如版本变更时重新配置并发)。
内容的提问来源于stack exchange,提问作者timmwagener
相关产品推荐
相关产品推荐

