I've spent the day fighting with API Gateway and AWS Serverless Express to no avail. My goal is to deploy an API Gateway, via Terraform (v0.12), that proxies all requests to an AWS Serverless Express based lambda. The connection between API Gateway and Lambda seems to exist, but tenuous, as any invocation (from API Gateway console or Postman) respond with 502 Bad Gateway, apparently due to timeout (so states the lambda CloudWatch logs). It does not appear that the lambda code actually runs, only that it spins up ineffectually.
The API Gateway and Lambda should support path parameters and query strings:
GET /some/path/:idget by idGET /some/path?query=paramget collectionPOST /some/pathcreate resourcePATCH /some/path/:idupdate resourceDELETE /some/path/:idremove resource
After several false starts, I've tried to make the API Gateway Terraform module as flexible as possible:
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
}