Been working on this semi-secure (will add HTTPS later) API Gateway. I've managed to deploy the TF into the cloud, and it built fine.
My main issue currently is that when I try to use the Invoke URL (whether it is the one with the segment or without), I receive a {"message":"Not Found"} I've looked through documentation, and I can see it's likely something to do with the routing setup that I employ. I can't exactly put my finger down on what's wrong with it... Can any of you spot the issue?
Here are the relevant parts relating to the gateway written with TF:
#create API Gateway HTTP API
resource "aws_apigatewayv2_api" "est_api" {
name = "est-api"
protocol_type = "HTTP"
}
resource "aws_apigatewayv2_integration" "lambda_integration" {
api_id = aws_apigatewayv2_api.est_api.id
integration_type = "AWS_PROXY"
integration_uri = aws_lambda_function.est_server.invoke_arn
}
resource "aws_apigatewayv2_route" "lambda_root" {
api_id = aws_apigatewayv2_api.est_api.id
route_key = "ANY /"
target = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}"
}
#give permission to api gateway to write logs
resource "aws_iam_role" "est_gw_role" {
name = "est-gw-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "apigateway.amazonaws"
}
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "est_gw" {
role = aws_iam_role.est_gw_role.name
policy_arn = aws_iam_policy.est_gw_policy.arn
}
resource "aws_apigatewayv2_stage" "est_gw_stage" {
api_id = aws_apigatewayv2_api.est_api.id
name = "prod"
auto_deploy = true
access_log_settings {
destination_arn = aws_cloudwatch_log_group.est_gw_logs.arn
format = jsonencode({
requestId = "$context.requestId",
ip = "$context.identity.sourceIp",
httpMethod = "$context.httpMethod",
routeKey = "$context.routeKey",
status = "$context.status",
protocol = "$context.protocol",
responseLength = "$context.responseLength"
})
}
}
resource "aws_lambda_permission" "apigw_lambda" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.est_server.function_name
principal = "apigateway.amazonaws"
source_arn = "${aws_apigatewayv2_api.est_api.execution_arn}/*"
}
output "est_service_url" {
value = aws_apigatewayv2_stage.est_gw_stage.invoke_url
}
Here is the URL for the whole repo as per 0x0b174's help.
Results as per STerliakov's suggestion:
command ran on each = curl -X GET ...amazonaws
With route_key API /
curl on ...amazon/prod = {"message":"Not Found"}
curl on ...amazon/prod/ = {"ERROR": "'http'"}
curl on ...amazon/ = {"message":"Not Found"}
curl on ...amazon = {"message":"Not Found"}
With route_key $default
curl on ...amazon/prod = {"ERROR": "'http'"}
curl on ...amazon/prod/ = {"ERROR": "'http'"}
curl on ...amazon/ = {"message":"Not Found"}
curl on ...amazon = {"message":"Not Found"}
with route_key API /{proxy+}
curl on ...amazon/prod = {"message":"Not Found"}
curl on ...amazon/prod/ = {"ERROR": "'http'"}
curl on ...amazon/ = {"message":"Not Found"}
curl on ...amazon = {"message":"Not Found"}
Only time I see anything in CloudWatch on the API Gateway is when I receive back the {"ERROR": "'http'"}. Whereas the Lambda only triggered (produced CloudWatch logs) in these cases:
With route_key API /
/prod/
/prod
With route_key $default
/prod/
With route_key API /{proxy+}
/prod/
My lambda expects a different input... but I expected it would at least return an appropriate error when I ran the curl