You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Terraform部署AWS API Gateway与Lambda时遇路由及调用错误

问题排查:AWS API Gateway + Terraform部署异常

问题现象

1. API Gateway调用返回404

Cloud9中执行curl命令:

curl -X "PUT" -H "Content-Type: application/json" -d "{
    \"id\": \"abcdef234\",
    \"price\": 12345,
    \"name\": \"myitem\"
}" $INVOKE_URL/items

返回结果:

{"message":"Not Found"}

2. Lambda直接调用返回400错误

执行命令:

aws lambda invoke --region=us-east-1 --function-name=$(terraform output -raw function_name) response.json

终端返回:

{  
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

但response.json内容:

{"statusCode":400,"body":"\"Unsupported route: \\\"undefined\\\"\"","headers":{"Content-Type":"application/json"}}

相关代码

Lambda函数代码

const AWS = require("aws-sdk");

const dynamo = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event, context) => {
  let body;
  let statusCode = 200;
  const headers = {
    "Content-Type": "application/json"
  };

  try {
    switch (event.routeKey) {
      case "DELETE /items/{id}":
        await dynamo
          .delete({
            TableName: "http-crud-tutorial-items",
            Key: {
              id: event.pathParameters.id
            }
          })
          .promise();
        body = `Deleted item ${event.pathParameters.id}`;
        break;
      case "GET /items/{id}":
        body = await dynamo
          .get({
            TableName: "http-crud-tutorial-items",
            Key: {
              id: event.pathParameters.id
            }
          })
          .promise();
        break;
      case "GET /items":
        body = await dynamo.scan({ TableName: "http-crud-tutorial-items" }).promise();
        break;
      case "PUT /items":
        let requestJSON = JSON.parse(event.body);
        await dynamo
          .put({
            TableName: "http-crud-tutorial-items",
            Item: {
              id: requestJSON.id,
              price: requestJSON.price,
              name: requestJSON.name
            }
          })
          .promise();
        body = `Put item ${requestJSON.id}`;
        break;
      default:
        throw new Error(`Unsupported route: \"${event.routeKey}\"`);
    }
  } catch (err) {
    statusCode = 400;
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers
  };
};

Terraform API Gateway配置

resource "aws_apigatewayv2_route" "crud_api_route1" {
  api_id    = aws_apigatewayv2_api.crud_api.id
  route_key = "GET /items/{id}"
  target    = "integrations/${aws_apigatewayv2_integration.crud_integration.id}"
}

resource "aws_apigatewayv2_route" "crud_api_route2" {
  api_id    = aws_apigatewayv2_api.crud_api.id
  route_key = "GET /items"
  target    = "integrations/${aws_apigatewayv2_integration.crud_integration.id}"
}


resource "aws_apigatewayv2_route" "crud_api_route" {
  api_id    = aws_apigatewayv2_api.crud_api.id
  route_key = "PUT /items"
  target    = "integrations/${aws_apigatewayv2_integration.crud_integration.id}"
}

resource "aws_apigatewayv2_route" "crud_api_route3" {
  api_id    = aws_apigatewayv2_api.crud_api.id
  route_key = "DELETE /items/{id}"
  target    = "integrations/${aws_apigatewayv2_integration.crud_integration.id}"
}

resource "aws_apigatewayv2_integration" "crud_integration" {
  api_id             = aws_apigatewayv2_api.crud_api.id
  integration_type   = "HTTP_PROXY"
  integration_method = "POST"
  integration_uri    = "https://a7fpzomc93.execute-api.us-west-1.amazonaws.com"
}

resource "aws_lambda_permission" "api_gw" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.http-crud-tutorial-function.function_name
  principal     = "apigateway.amazonaws.com"

  source_arn = "${aws_apigatewayv2_api.crud_api.execution_arn}/*/*"
}

核心问题与修复方案

  1. API Gateway集成类型错误
    当前使用HTTP_PROXY类型,集成Lambda需改为AWS_PROXY,且integration_uri必须指向Lambda的Invoke ARN,而非固定API地址。

  2. 缺失API Gateway部署与阶段
    未创建aws_apigatewayv2_deployment和aws_apigatewayv2_stage资源,导致配置的路由未生效,引发404错误。

  3. Lambda直接调用无Event参数
    用aws lambda invoke直接调用时未传入模拟的API Gateway事件,event.routeKey为undefined导致400,属于正常现象,需通过API Gateway触发或传入模拟Event测试。

修改后的Terraform集成与部署配置示例

# 修正Lambda集成配置
resource "aws_apigatewayv2_integration" "crud_integration" {
  api_id             = aws_apigatewayv2_api.crud_api.id
  integration_type   = "AWS_PROXY"
  integration_method = "POST"
  integration_uri    = aws_lambda_function.http-crud-tutorial-function.invoke_arn
}

# 新增部署资源,路由变更时自动重新部署
resource "aws_apigatewayv2_deployment" "crud_deployment" {
  api_id      = aws_apigatewayv2_api.crud_api.id
  triggers = {
    redeployment = sha1(jsonencode([
      aws_apigatewayv2_route.crud_api_route,
      aws_apigatewayv2_route.crud_api_route1,
      aws_apigatewayv2_route.crud_api_route2,
      aws_apigatewayv2_route.crud_api_route3,
      aws_apigatewayv2_integration.crud_integration
    ]))
  }

  lifecycle {
    create_before_destroy = true
  }
}

# 新增阶段资源,对外提供访问入口
resource "aws_apigatewayv2_stage" "crud_stage" {
  api_id        = aws_apigatewayv2_api.crud_api.id
  name          = "prod"
  deployment_id = aws_apigatewayv2_deployment.crud_deployment.id
}

内容的提问来源于stack exchange,提问作者killydev767

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:40:14