调用终端节点URL时未找到AWS API Gateway 404页面错误 [英] AWS API Gateway 404 page not found error when invoking endpoint url
问题描述
我有一个在ECS Fargate
上运行的API,该API接受GET
方法请求.我将API Gateway
端点放在其前面,并在私有子网中通过VPC_LINK
与NLB
集成.当我使用调用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屋!