AWS API Gateway 404 page not found error when invoking endpoint url

随声附和 提交于 2019-12-11 15:37:47

问题


I have an API running on ECS Fargate that accepts GET method requests. I put an API Gateway endpoint in front of it with a VPC_LINK integration with an NLB in a private subnet. When I send a GET request using the invoke url, I get a 404 page not found error. I am confused why I am getting this. I set up every component - the NLB listener, the target group, and my host and container ports in my task definition - on 8000/tcp. So, I am not sure why this error is happening. My Fargate task is also running successfully and passing all health checks. When I test the container locally doing curl -X GET localhost/nmapscan:8000 it works fine. Below are my configurations in Terraform as well as screenshots from the console.

Terraform:

resource "aws_lb" "myapis" {
  name               = "my-apis"
  internal           = true
  load_balancer_type = "network"
  subnets            = ["${module.vpc.private_subnets}"]

  enable_deletion_protection = false

  tags = {
    Environment = "dev"
  }
}

resource "aws_security_group" "ecs_tasks" {
  name        = "ecs-tasks"
  description = "allow inbound access from the NLB only"
  vpc_id      = "${module.vpc.vpc_id}"

  ingress {
    protocol        = "tcp"
    from_port       = 8000
    to_port         = 8000
    cidr_blocks     = ["10.10.11.0/24", "10.10.12.0/24", "10.10.13.0/24"]
  }

  egress {
    protocol    = "-1"
    from_port   = 0
    to_port     = 0
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_lb_target_group" "test" {
  name     = "test-api"
  port     = 8000
  protocol = "TCP"
  target_type = "ip"
  vpc_id   = "${module.vpc.vpc_id}"

  stickiness{
    enabled = false
    type = "lb_cookie"
  }
  health_check{
    interval = 30
    port     = 8000
    protocol = "tcp"
    healthy_threshold = 2
    unhealthy_threshold = 2
  }
}

resource "aws_lb_listener" "test" {
  load_balancer_arn = "${aws_lb.myapis.id}"
  port              = "8000"
  protocol          = "TCP"

  default_action {
    target_group_arn = "${aws_lb_target_group.test.id}"
    type             = "forward"
  }
}

resource "aws_api_gateway_vpc_link" "myapi" {
  name        = "my_api_link"
  description = "VPC link for API NLB"
  target_arns = ["${aws_lb.myapis.arn}"]
}

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"
}

resource "aws_api_gateway_integration" "integrationtest" {
  connection_type = "VPC_LINK"
  connection_id   = "${aws_api_gateway_vpc_link.myapi.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("https://%s:8000/", aws_lb.myapis.dns_name)}"
}

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"
}

resource "aws_ecs_cluster" "goapi" {
  name = "goapis"
}

data "aws_iam_role" "ecs_task_execution_role" {
  name = "ecsTaskExecutionRole"
}

resource "aws_ecs_task_definition" "test" {
  family                   = "test"
  requires_compatibilities = ["FARGATE"]
  network_mode = "awsvpc"
  cpu = 256
  memory = 512
  execution_role_arn = "${data.aws_iam_role.ecs_task_execution_role.arn}"

  container_definitions = "${file("test-service.json")}"
}

resource "aws_ecs_service" "test" {
  name            = "test-service"
  cluster         = "${aws_ecs_cluster.goapi.id}"
  task_definition = "${aws_ecs_task_definition.test.arn}"
  launch_type     = "FARGATE"
  desired_count   = 1

  network_configuration {
    subnets         = ["${module.vpc.private_subnets}"]
    security_groups = ["${aws_security_group.ecs_tasks.id}"]
  }
  load_balancer {
    target_group_arn = "${aws_lb_target_group.test.id}"
    container_name   = "test-service"
    container_port   = 8000
  }

    depends_on = [
    "aws_lb_listener.test",
  ]
}

Task Definiton:

[   
  {
    "name": "test-service",
    "image": "12345678910.dkr.ecr.us-east-1.amazonaws.com/myimages:latest",
    "cpu": 256,
    "memory": 512,
    "essential": true,
    "portMappings": [
      {
        "containerPort": 8000,
        "hostPort": 8000
      }
    ]
  }
]

Screenshots:


回答1:


EDIT Looks like the answer came about here, might be worth deprecating this post.

Unless you are successfully SIGV4 Signing your requests with IAM auth on your Method Request or have mapped custom Gateway Responses in case of auth failures, API Gateway will not return a 404, and neither will the NLB thus this response has to be coming from beyond the NLB in this stack. You should be able to confirm this by looking in your API Gateway CloudWatch logs (enable full request/response data on the stage).

NOTE: You should match the request id in your CloudWatch logs to the API GW response header "x-amzn-requestid", for example:

x-amzn-requestid: 7cc765bb-4086-45f4-9450-1a2a3c4e67d5

In the logs, you should see it say something like "Sending request to..." or a line about the response it gets back from that request. That is an indication that API Gateway received the request, sent it to the backend integration and received a 404 in return.

I'd say the next steps are to implement debug logging on your integration to log the requests coming in, and the properties of those requests so you can determine where the breakdown is. Seems like the request is to a URI your application isn't configured to respond to.



来源:https://stackoverflow.com/questions/58089140/aws-api-gateway-404-page-not-found-error-when-invoking-endpoint-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!