如何通过Terraform配置API Gateway指向Lambda指定版本而非$LATEST
你在API Gateway集成里使用的module.my-lambda.this_lambda_function_invoke_arn是Lambda的基础调用ARN,本身不带任何版本路由标识——哪怕你开启了publish=true生成了正式发布版本,这个输出的ARN默认就是指向无版本的$LATEST,根本不会匹配你预期的正式版本。
方案1:直接绑定固定正式发布版本
如果你的API流量需要硬绑定到某次发布的固定版本,只需要把Lambda调用ARN和对应的正式版本号拼接起来即可,不需要额外新增资源:
调整API Gateway模块的集成配置:
integrations = { "GET /mymethod" = { integration_type = "AWS_PROXY" integration_http_method = "POST" payload_format_version = "2.0" # 拼接带版本号后缀的调用ARN lambda_arn = "${module.my-lambda.this_lambda_function_invoke_arn}:${module.my-lambda.this_lambda_function_version}" } }
注意:这种绑定方式会把流量钉死在当前的版本号上,后续你给Lambda发新版本、生成新的正式版本号之后,必须手动修改Terraform配置才能把API流量切过去,适合流量需要完全固定版本的严苛生产场景。
方案2:绑定你已经创建的自定义别名(推荐)
你本来就已经创建了Lambda别名模块,用别名对接API Gateway的灵活性比硬绑固定版本高很多——后续要切流量的时候,只要把别名指向的版本切到新的正式发布版,API Gateway不需要改任何配置就能自动同步流量,还能和你依赖的Provisioned Concurrency能力完全兼容(毕竟Provisioned Concurrency本来就需要绑定在正式版本/别名上)。
调整API Gateway模块的集成配置,直接引用别名模块输出的带别名标识的调用ARN:
integrations = { "GET /mymethod" = { integration_type = "AWS_PROXY" integration_http_method = "POST" payload_format_version = "2.0" # 直接用别名模块输出的调用ARN lambda_arn = module.alias.this_lambda_alias_invoke_arn } }
补充:你使用的v1.31.0版本的Lambda别名子模块,默认就会输出
this_lambda_alias_invoke_arn字段,这个值本身就是已经拼好后缀的可用调用ARN,不需要手动拼接。如果遇到版本适配的问题拿不到这个输出,也可以手动拼接为"${module.my-lambda.this_lambda_function_invoke_arn}:${module.alias.name}",效果完全一致。
Terraform apply完成之后,到API Gateway控制台查看对应集成的Lambda ARN结尾:如果结尾带着:加版本号/别名(比如...function:my-lambda:2、...function:my-lambda:prod-latest),就说明配置生效了;如果结尾没有任何冒号加后缀,就说明还是默认路由到$LATEST的状态,需要回头检查ARN配置。
内容的提问来源于stack exchange,提问作者onkami

