如何通过CDK/SAM创建集成不同Lambda版本的API Gateway V2多阶段
解决方案
1. 解决Lambda版本自动删除问题
CDK中默认未被显式引用的Lambda版本会在新部署时被自动清理,可通过两个配置解决:
- 给每个Lambda版本设置
RemovalPolicy.RETAIN保留策略,避免旧版本被删除 - 给Lambda版本构造函数传入随代码更新动态变化的参数(如代码哈希、构建ID作为
description),保证每次代码变更时自动生成新的版本,不会复用旧版本ID
示例代码:
from aws_cdk import RemovalPolicy import aws_cdk.aws_lambda as lambda_ import aws_cdk.aws_iam as iam # 定义Lambda函数 lambda_func = lambda_.Function(self, "MyFunction", runtime=lambda_.Runtime.PYTHON_3_9, handler="index.handler", code=lambda_.Code.from_asset("./lambda") ) # 生成新版本,每次代码变更自动创建新实例,旧版本保留 lambda_version = lambda_.Version(self, f"LambdaVersion-{lambda_func.current_version.version}", lambda_=lambda_func, removal_policy=RemovalPolicy.RETAIN )
如果是SAM模板,直接配置AutoPublishAlias即可,原生支持保留旧版本无需额外配置。手动管理的dev别名无需在CDK/SAM中定义指向规则,仅需后续在Lambda控制台手动调整即可。
2. 解决API Gateway V2多阶段不同Lambda集成问题
API Gateway V2 HttpApi确实不支持不同阶段绑定不同部署配置,但你可以通过阶段变量动态路由到不同Lambda版本/别名实现需求,无需创建多个Deployment:
- 创建HttpApi时关闭默认阶段,集成配置使用阶段变量占位符指向Lambda版本/别名
- 为每个阶段配置对应
lambda_alias阶段变量,分别指向不同的Lambda版本号或dev别名 - 配置Lambda权限允许API Gateway所有阶段调用对应Lambda资源
示例代码:
import aws_cdk.aws_apigatewayv2 as apigwv2 import aws_cdk.aws_apigatewayv2_integrations as integrations # 创建HttpApi,关闭默认阶段 http_api = apigwv2.HttpApi(self, "cdk_http_api", create_default_stage=False ) # 配置通用Lambda集成,使用阶段变量动态指向目标版本/别名 lambda_integration = integrations.HttpLambdaIntegration("LambdaIntegration", handler=lambda_func, uri=f"arn:aws:lambda:{self.region}:{self.account}:function:MyFunction:${{stageVariables.lambda_alias}}" ) # 添加通用路由 http_api.add_routes( path="/{proxy+}", methods=[apigwv2.HttpMethod.ANY], integration=lambda_integration ) # 配置Lambda调用权限 lambda_func.add_permission("ApiGatewayInvoke", principal=iam.ServicePrincipal("apigateway.amazonaws.com"), action="lambda:InvokeFunction", source_arn=f"arn:aws:execute-api:{self.region}:{self.account}:{http_api.http_api_id}/*/*/*" )
3. 解决阶段覆盖、实现阶段追加
每个阶段使用唯一的逻辑ID定义,旧阶段的构造代码不要删除,即可保证部署时不会删除旧阶段:
# 新增v1版本阶段,指向Lambda版本1 apigwv2.HttpStage(self, "StageV1", http_api=http_api, stage_name="v1", stage_variables={ "lambda_alias": "1" }, auto_deploy=True ) # 新增dev阶段,指向手动管理的dev别名 apigwv2.HttpStage(self, "StageDev", http_api=http_api, stage_name="dev", stage_variables={ "lambda_alias": "dev" }, auto_deploy=True ) # 后续新增v2版本时,仅需添加以下代码,旧阶段v1、dev都会保留 # apigwv2.HttpStage(self, "StageV2", # http_api=http_api, # stage_name="v2", # stage_variables={ # "lambda_alias": "2" # }, # auto_deploy=True # )
每次部署新版本时,仅需新增对应版本的阶段定义,旧阶段代码保留即可实现阶段追加,不会覆盖。
内容的提问来源于stack exchange,提问作者Amer Sawan
相关产品推荐
相关产品推荐

