用于Lambda代理集成的Terraform API网关

时间:2019-11-17 04:27:30

标签: aws-lambda terraform aws-api-gateway

我整天都在与API Gateway战斗,AWS Serverless Express毫无结果。我的目标是通过proxies all requests通过Terraform(v0.12)将API网关部署到基于AWS Serverless Express的lambda。 API网关和Lambda之间的连接似乎存在,但很脆弱,因为任何调用(从API网关控制台或Postman)都响应502 Bad Gateway,这显然是由于超时(因此声明了Lambda CloudWatch日志)。看来lambda代码实际上并没有运行,只是它无效地旋转了。

API网关和Lambda应该支持路径参数和查询字符串:

  1. GET /some/path/:id通过ID获取
  2. GET /some/path?query=param得到 集合
  3. POST /some/path创建资源
  4. PATCH /some/path/:id更新资源
  5. DELETE /some/path/:id删除资源

在几次错误的开始之后,我尝试使API Gateway Terraform模块尽可能灵活:

resource "aws_api_gateway_rest_api" "rest_api" {
  name        = "${var.application_name} API"
  description = var.description
}

resource "aws_api_gateway_resource" "proxy" {
  rest_api_id = aws_api_gateway_rest_api.rest_api.id
  parent_id   = aws_api_gateway_rest_api.rest_api.root_resource_id # aws_api_gateway_resource.version.id
  path_part   = "{proxy+}"
}

resource "aws_api_gateway_method" "method" {
  rest_api_id   = aws_api_gateway_rest_api.rest_api.id
  resource_id   = aws_api_gateway_resource.proxy.id
  http_method   = "ANY"
  authorization = "NONE"

  request_parameters = {
    "method.request.path.proxy" = true
  }
}

resource "aws_api_gateway_integration" "integration" {
  rest_api_id             = aws_api_gateway_rest_api.rest_api.id
  resource_id             = aws_api_gateway_resource.proxy.id
  http_method             = aws_api_gateway_method.method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = "arn:aws:apigateway:${local.region}:lambda:path/2015-03-31/functions/${var.lambda_arn}/invocations"
}

resource "aws_api_gateway_deployment" "apig_deployment" {
  depends_on = [
    "aws_api_gateway_resource.proxy",
    "aws_api_gateway_method.method",
    "aws_api_gateway_integration.integration"
  ]

  rest_api_id = aws_api_gateway_rest_api.rest_api.id
  stage_name  = var.api_stage_name

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_lambda_permission" "apig_to_lambda" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = var.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "arn:aws:execute-api:${local.region}:${local.account_id}:${aws_api_gateway_rest_api.rest_api.id}/*/*/*" # TODO: lock this down
}

1 个答案:

答案 0 :(得分:0)

您收到502错误,表明api网关收到的响应不正确。

已经说过,您的应用程序似乎返回了json响应。您可以在下面尝试/确认设置吗?

  1. 在lambda配置中添加正确的二进制mime类型。有关更多详细信息,请参见here

  2. 如下所示,在api网关端允许使用相同的mime类型或通配符。

    resource "aws_api_gateway_rest_api" "rest_api" {
      name        = "${var.application_name} API"
      description = var.description

       // Wildcard mimes, accept any
      binary_media_types = ["*/*"]
    }