Terraform部署Lambda集成REST API:POST正常GET报500错误求助
问题
我用Terraform部署了一个包含GET和POST方法的AWS REST API,两个方法分别对接代码完全相同的Lambda函数(返回"Hello World"),但POST请求正常返回200,GET请求始终返回500错误:
- 当GET集成类型设为
MOCK时:Execution failed due to configuration error: No match for output mapping and no default output mapping configured. Endpoint Response Status Code: 200 - 当GET集成类型设为
AWS_PROXY时:Lambda invocation failed with status: 403. Lambda request id: 5b23639d-f6fb-4130-acf0-15db9a2f76b0
排查方向与解决方案
1. 修正GET集成的integration_http_method配置
在AWS_PROXY模式下,不管API对外暴露的HTTP方法是GET还是POST,API Gateway调用Lambda时的integration_http_method必须固定设为POST——这是AWS的硬性规则,和外部请求方法无关。你的POST集成配置正确,但GET集成错误地使用了GET,这是核心问题。
2. 移除GET集成中多余的request_templates
AWS_PROXY模式下,API Gateway会自动将完整的请求上下文转发给Lambda,不需要手动配置请求模板。多余的模板会干扰正常的请求转发逻辑,直接删除即可。
3. 确认Lambda权限配置
即使你认为IAM权限正常,仍需确保API Gateway拥有调用GET对应Lambda的权限。可以通过Terraform的aws_lambda_permission资源明确授权:
resource "aws_lambda_permission" "api_gateway_get" { statement_id = "AllowAPIGatewayInvokeGet" action = "lambda:InvokeFunction" function_name = aws_lambda_function.lambda_hello_world_v1_get.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.hello_world_v1.execution_arn}/*/GET/test" }
4. 修正Deployment的依赖关系
当前Deployment仅依赖Method资源,应该同时依赖Integration资源,确保部署时集成配置已经完全生效:
resource "aws_api_gateway_deployment" "hello_world_v1" { rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id depends_on = [ aws_api_gateway_integration.hello_world_v1_get, aws_api_gateway_integration.hello_world_v1_post ] }
修正后的Terraform核心配置
################################################################################ # REST API and Resource ################################################################################ resource "aws_api_gateway_rest_api" "hello_world_v1" { name = "hello_world_v1" } resource "aws_api_gateway_resource" "hello_world_v1" { parent_id = aws_api_gateway_rest_api.hello_world_v1.root_resource_id rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id path_part = "test" } ################################################################################ # GET - method and integration(已修正) ################################################################################ resource "aws_api_gateway_method" "hello_world_v1_get" { rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id resource_id = aws_api_gateway_resource.hello_world_v1.id http_method = "GET" authorization = "NONE" } resource "aws_api_gateway_integration" "hello_world_v1_get" { rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id resource_id = aws_api_gateway_method.hello_world_v1_get.resource_id http_method = aws_api_gateway_method.hello_world_v1_get.http_method integration_http_method = "POST" # 关键修正:必须设为POST type = "AWS_PROXY" uri = aws_lambda_function.lambda_hello_world_v1_get.invoke_arn } # 新增Lambda权限授权 resource "aws_lambda_permission" "api_gateway_get" { statement_id = "AllowAPIGatewayInvokeGet" action = "lambda:InvokeFunction" function_name = aws_lambda_function.lambda_hello_world_v1_get.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.hello_world_v1.execution_arn}/*/GET/test" } ################################################################################ # POST - method and integration(保持不变) ################################################################################ resource "aws_api_gateway_method" "hello_world_v1_post" { rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id resource_id = aws_api_gateway_resource.hello_world_v1.id http_method = "POST" authorization = "NONE" } resource "aws_api_gateway_integration" "hello_world_v1_post" { rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id resource_id = aws_api_gateway_method.hello_world_v1_post.resource_id http_method = aws_api_gateway_method.hello_world_v1_post.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.lambda_hello_world_v1_post.invoke_arn } # 新增POST对应的Lambda权限(如果之前未配置) resource "aws_lambda_permission" "api_gateway_post" { statement_id = "AllowAPIGatewayInvokePost" action = "lambda:InvokeFunction" function_name = aws_lambda_function.lambda_hello_world_v1_post.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.hello_world_v1.execution_arn}/*/POST/test" } ################################################################################ # Stage and Deployment(修正依赖) ################################################################################ resource "aws_api_gateway_deployment" "hello_world_v1" { rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id depends_on = [ aws_api_gateway_integration.hello_world_v1_get, aws_api_gateway_integration.hello_world_v1_post ] } resource "aws_api_gateway_stage" "hello_world_v1" { deployment_id = aws_api_gateway_deployment.hello_world_v1.id rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id stage_name = "development" }
Lambda代码(保持不变)
import json def lambda_handler(event, context): return { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "body": json.dumps("Hello World") }
内容的提问来源于stack exchange,提问作者Srikar-231232
相关产品推荐
相关产品推荐

