3

I am trying to configure API Gateway to route requests to a specific route on my backend GO microservice. I am using a GET request method with a VPC_LINK integration with an NLB, which routes to my backend microservice running in Fargate. This is a simple REST api written in GO. On the service side, in my handler, I put a catch all response for my stage route and then a "Hello World" response for the /nmapscan route, which is what I am trying to hit. However, when I try to hit my backend service with the invocation url, I keep getting the catch all response, despite the request path appearing correct in my request response output. I am new to API Gateway and I have a feeling I am missing something simple. Also, when I ran the container locally, I attached a shell and ran curl localhost:8000/v1/nmapscan and got the correct "Hello World!" response. Below is the response, my configuration, as well as the response from the flow logs:

RESPONSE:

user$ curl -v -X GET https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/v1/nmapscan/
> GET /v1/nmapscan/ HTTP/2
> Host: xxxxxxxxxx.execute-api.us-east-1.amazonaws.com
> User-Agent: curl/7.54.0
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< content-type: application/json
< content-length: 27
< date: Wed, 25 Sep 2019 20:24:16 GMT
< x-amzn-requestid: df90f051-dbdd-405f-a708-73668ad955f1
< x-amz-apigw-id: XXXXXXXXXXX=
< x-amzn-trace-id: Root=1-5d8bccf0-44ebf9c5af13c90e1636de42
< x-cache: Miss from cloudfront
< via: 1.1 b7ddb18a56b4bad68ca78b085e9ca451.cloudfront.net (CloudFront)
< x-amz-cf-pop: EWR52-C2
< x-amz-cf-id: lvT1CGlv2fboFJ5AxE917Jr61Nwb4fQOwbranZ3s_vz0EJULhcwudQ==
< 
* Connection #0 to host xxxxxxxxx.execute-api.us-east-1.amazonaws.com left intact
This is the catch all path!

As you can see, this is returning the catch all response. It should return "Hello World!".

Configuration:

resource "aws_api_gateway_rest_api" "GOAPI" {
  name        = "GO"
  description = "REST API for GO APIs"
}

resource "aws_api_gateway_resource" "test" {
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  parent_id   = "${aws_api_gateway_rest_api.GOAPI.root_resource_id}"
  path_part   = "nmapscan"
}

resource "aws_api_gateway_method" "testmethod" {
  rest_api_id   = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id   = "${aws_api_gateway_resource.test.id}"
  http_method   = "GET"
  authorization = "NONE"
  request_parameters = {
    "method.request.path.nmapscan" = true
  }
}

resource "aws_api_gateway_integration" "integrationtest" {
  connection_type = "VPC_LINK"
  connection_id   = "${aws_api_gateway_vpc_link.test.id}"
  type = "HTTP"
  integration_http_method = "GET"
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id = "${aws_api_gateway_resource.test.id}"
  http_method = "${aws_api_gateway_method.testmethod.http_method}"
  uri = "${format("http://%s:8000", aws_lb.myapis.dns_name)}"

//  request_parameters = {
//    "integration.request.path.nmapscan" = "method.request.path.nmapscan"
//  }
}


resource "aws_api_gateway_method_response" "test-200" {
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id = "${aws_api_gateway_resource.test.id}"
  http_method = "${aws_api_gateway_method.testmethod.http_method}"
  status_code = "200"

  response_models = {
    "application/json" = "Empty"
  }
}

resource "aws_api_gateway_integration_response" "testintegrationresponse" {
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id = "${aws_api_gateway_resource.test.id}"
  http_method = "${aws_api_gateway_method.testmethod.http_method}"

  status_code = "${aws_api_gateway_method_response.test-200.status_code}"

  response_templates = {
    "application/json" = ""
  }
}

resource "aws_api_gateway_deployment" "testdeploy" {
  depends_on = ["aws_api_gateway_integration.integrationtest"]

  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  stage_name = "v1"
}

enter image description here

enter image description here

Flow Logs:

(fdaa14d3-08df-4847-ba63-a9644a65d265) Method request body before transformations:
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint request URI: http://xxx-yyy-zzzzzzz.elb.us-east-1.amazonaws.com:8000
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint request headers: {x-amzn-apigateway-api-id=cqq6k2xrw3, Accept=application/json, User-Agent=AmazonAPIGateway_cqq6k2xrw3, Host=xxx-yyy-zzzzzz.elb.us-east-1.amazonaws.com, X-Amzn-Trace-Id=Root=1-5d8c2eee-51c73680b040aea02ab1dd14}
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint request body after transformations:
(fdaa14d3-08df-4847-ba63-a9644a65d265) Sending request to http://xxx-yyy-zzzzzzz.elb.us-east-1.amazonaws.com:8000
(fdaa14d3-08df-4847-ba63-a9644a65d265) Received response. Status: 200, Integration latency: 15 ms
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint response headers: {Content-Type=application/json, Date=Thu, 26 Sep 2019 03:22:22 GMT, Content-Length=27}
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint response body before transformations: This is the catch all path!
(fdaa14d3-08df-4847-ba63-a9644a65d265) Method response body after transformations: This is the catch all path!
(fdaa14d3-08df-4847-ba63-a9644a65d265) Method response headers: {X-Amzn-Trace-Id=Root=1-5d8c2eee-51c73680b040aea02ab1dd14, Content-Type=application/json}
(fdaa14d3-08df-4847-ba63-a9644a65d265) Successfully completed execution
(fdaa14d3-08df-4847-ba63-a9644a65d265) Method completed with status: 200

1 Answer 1

1

Your post looks suspiciously like this

If you are convinced it's not the things mentioned in that response, then I would check the routing in your integration request.

The URI of your curl request is /v1/nmapscan/ which means API Gateway will look at STAGE v1, resource /nmapscan. Once that occurs, API GW sends the request to the VPC Link based on the uri configured in the Integration Request. I'm not super familiar with Terraform, but it looks like you are sending it to:

http://aws_lb.myapis.dns_name:8000

I also see that you have "request parameters" defined in terraform(but maybe commented out?):

    //  request_parameters = {
    //    "integration.request.path.nmapscan" = "method.request.path.nmapscan"
    //  }

I would check that after deployment, the Integration Request in the API GW Console shows that this is being routed to the proper route. Without knowing for sure, I'm assuming your application path is actually http://aws_lb.myapis.dns_name/nmapscan:8000 and that's not being passed correctly to the NLB because it isn't properly mapping for some reason in the Integration Request.

All of that being said, the easiest way to see what the URI is when the request is being sent to the NLB is to enable API Gateway execution logs, and enable full request/response data on those logs. It will give you something similar to this:

    (32e76dc1-2e80-11e9-b849-1d4cbf2f1403) Endpoint request body after transformations: {"resource":"/testproxy","path":"/testproxy","httpMethod":"GET","headers":[TRUNCATED]
    (32e76dc1-2e80-11e9-b849-1d4cbf2f1403) Sending request to [TRUNCATED]

I truncated for brevity but you can see the path definition there. It will be useful to look at that to narrow down where the error is originating.

Sign up to request clarification or add additional context in comments.

4 Comments

I enabled flow logs and updated my question with the response from the logs. It looks like the URI is set to the NLB..
Interesting, can you post a screen shot of the UI configuration for the "Integration Request"? When I look at mine in the UI, I see that it has the "Endpoint URL" Field and a "Path Parameters" field. If your application is expecting the nmapscan route as a path parameter you want it to show up in the latter, but if it's expecting in the URI path itself then you should see the path in the URL. Either way though, looks like it's not being configured or API Gateway isn't interpreting it based on your flow logs.
Another note too, API Gateway uses SNI for TLS negotiation, so it doesn't actually send the request to the URL you specify, it always sends the request to the VPC endpoint but it includes a Host header of the domain you have in the 'URL' section of your Integration Response, which is required when using SNI to ensure the TLS negotiation succeeds. So don't get too caught up on the URL API Gateway is sending it to.
Turns out I was using the incorrect URI. When I changed it to http://xxx-yyy-zzzzzzz.elb.us-east-1.amazonaws.com:8000/nmapscan, I got the correct response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.