调用终端节点URL时未找到AWS API Gateway 404页面错误 [英] AWS API Gateway 404 page not found error when invoking endpoint url

查看:215
本文介绍了调用终端节点URL时未找到AWS API Gateway 404页面错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在ECS Fargate上运行的API,该API接受GET方法请求.我将API Gateway端点放在其前面,并在私有子网中通过VPC_LINKNLB集成.当我使用调用URL发送GET请求时,出现404 page not found错误.我很困惑为什么要得到这个.我在8000/tcp上的任务定义中设置了每个组件-NLB侦听器,目标组以及主机和容器端口.因此,我不确定为什么会发生此错误.我的Fargate任务也正在成功运行,并通过了所有运行状况检查.当我在本地进行curl -X GET localhost/nmapscan:8000测试容器时,它工作正常.以下是我在Terraform中的配置以及控制台中的屏幕截图.

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:

推荐答案

编辑 看来答案来自此处,可能不推荐该帖子.

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

除非成功通过SIGV4在方法请求上使用IAM auth签名您的请求,或者在身份验证失败的情况下映射了自定义网关响应,否则API网关将不会返回404,并且NLB也不会返回,因此此响应必须到来在此堆栈中超出NLB.您应该可以通过查看 API来确认这一点Gateway CloudWatch日志(在舞台上启用完整的请求/响应数据).

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).

注意:您应该将CloudWatch日志中的请求ID与API GW响应标头"x-amzn-requestid"进行匹配,例如:

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

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

在日志中,您应该看到它说出类似正在将请求发送到..."或关于从该请求返回的响应的一行.这表明API网关已接收到该请求,将其发送到后端集成并返回了404.

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.

我要说的下一步是在集成上实现调试日志记录,以记录进入的请求以及这些请求的属性,以便您可以确定故障所在.似乎该请求是针对您的应用未配置为响应的URI.

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.

这篇关于调用终端节点URL时未找到AWS API Gateway 404页面错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆