skip to Main Content

So I have been trying to solve this issue for a couple of evenings by now, and I still feel that there is not really any progress.

So what I’m trying to do, is to set up a lambda authorizer for my API gateway.

I have attached my authorizer both with Terraform and through the console without any luck. For my Terraform configuration, I have something like this:

resource "aws_apigatewayv2_authorizer" "lambda_authorizer" {
  api_id                            = aws_apigatewayv2_api.api.id
  authorizer_type                   = "REQUEST"
  identity_sources                  = ["$request.header.Authorization"]
  name                              = "lambda_authorizer-${var.app_name}-${var.environment}"
  authorizer_payload_format_version = "2.0"
  authorizer_result_ttl_in_seconds  = 0
  enable_simple_responses           = true
  authorizer_uri                    = aws_lambda_function.authorizer.invoke_arn
}

resource "aws_lambda_permission" "my_authorizer_lambda_permission" {
  statement_id  = "AllowAPIGatewayInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.authorizer.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "arn:aws:execute-api:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:${aws_apigatewayv2_api.api.id}/*/*/*"
}

resource "aws_apigatewayv2_integration" "integration" {
  api_id                 = aws_apigatewayv2_api.api.id
  integration_type       = "HTTP_PROXY"
  integration_uri        = aws_service_discovery_service.ecs-discovery-service.arn
  integration_method     = "ANY"
  connection_type        = "VPC_LINK"
  connection_id          = aws_apigatewayv2_vpc_link.vpc_link.id
  payload_format_version = "1.0"
}

resource "aws_apigatewayv2_route" "route" {
  api_id             = aws_apigatewayv2_api.api.id
  route_key          = "ANY /{proxy+}"
  target             = "integrations/${aws_apigatewayv2_integration.integration.id}"
  authorization_type = "CUSTOM"
  authorizer_id      = aws_apigatewayv2_authorizer.lambda_authorizer.id
  depends_on         = [aws_apigatewayv2_authorizer.lambda_authorizer]
}

resource "aws_apigatewayv2_stage" "stage" {
  api_id      = aws_apigatewayv2_api.api.id
  name        = "${var.app_name}-${var.environment}"
  auto_deploy = true

  default_route_settings {
    logging_level            = "INFO"
    detailed_metrics_enabled = true
    data_trace_enabled       = true
    throttling_rate_limit    = 20 #Amount of requests per second
    throttling_burst_limit   = 50 #Concurrent requests
  }
  access_log_settings {
    destination_arn = aws_cloudwatch_log_group.api_gw_access_log_group.arn
    format = jsonencode({
      requestId               = "$context.requestId"
      sourceIp                = "$context.identity.sourceIp"
      requestTime             = "$context.requestTime"
      protocol                = "$context.protocol"
      httpMethod              = "$context.httpMethod"
      resourcePath            = "$context.resourcePath"
      routeKey                = "$context.routeKey"
      status                  = "$context.status"
      responseLength          = "$context.responseLength"
      integrationErrorMessage = "$context.integrationErrorMessage"
      }
    )
  }
}

Above, I left unnecessary stuff out. But the gist is, that the deployment deploys as it should and the authorizer gets attached to my API Gateway, however I encounter the following error for both creating with Terraform and AWS console: (this scr shot is for when i tried with the console with a different source_arn)

enter image description here

I have a hard time understanding whats actually going on here, since there is a route with path /* …..

I tried experimenting with this and figured out, that when I create a custom lambda based endpoint for the same function (not authorizer, but just an API endpoint), the error dissapears – but the problem obviously still persists… Super strange!

In continuation, I can see that the requests hits my API gateway, but nothing is printed in the Lambda logs – Which I guess is why im getting a 403 status code returned (e.g. default return if Lambda Authorizer doesn’t return a policy)

Anyway, I’m stuck here without any further progress. Please help me out.


Update

I tried to change the source_arn to:

source_arn = "${aws_apigatewayv2_api.api.execution_arn}/authorizers/${aws_apigatewayv2_authorizer.lambda_authorizer.id}"

Still no luck.


Update 9/9

So I tried changing the source_arn to account for different lambda versions:

source_arn = "${aws_apigatewayv2_api.api.execution_arn}/authorizers/${aws_apigatewayv2_authorizer.lambda_authorizer.id}/*/*"

Additionally I tried:

source_arn = "${aws_apigatewayv2_api.api.execution_arn}/*"

Still looking at the same error, nor can I see that the request is hitting my lambda (only API gateway)

2

Answers


  1. I think one of the possible reasons is that your Lambda had many versions, but you added the resource-based policy only to the unversioned function and not to the versioned ones.

    In the terraform resource aws_lambda_permission, you have to specify the qualifier argument, use the Lambda version as the value for it.

    Otherwise you can also try to add /*/* at the end:

    source_arn    = "source_arn = "${aws_apigatewayv2_api.api.execution_arn}/authorizers/${aws_apigatewayv2_authorizer.lambda_authorizer.id}/*/*"
    
    
    Login or Signup to reply.
  2. When you add an authorizer to an existing API GW, it does not create a deployment, and the authorizer will not change until you do so which Terraform makes it hard to do. see here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search