0

A manually created API Gateway and lambda endpoint has this "/results" in lambda console:

lj

However when I try to create similar combination of API Gateway + lambda in another region using TF code, it has no "/result" at the end.

"API endpoint: https://91oojllzci.execute-api.us-east-2.amazonaws.com/"

TF code:

resource "aws_apigatewayv2_api" "main_apigateway" {
  name          = "apigateway-vote"
  protocol_type = "HTTP"
  
}

resource "aws_apigatewayv2_stage" "default" {
  api_id = aws_apigatewayv2_api.main_apigateway.id

  name        = "$default"
  auto_deploy = true
}


# ###########################################
# # RESULT lambda backend integration
# ###########################################

resource "aws_apigatewayv2_integration" "result_integration" {
  api_id = aws_apigatewayv2_api.main_apigateway.id


  # I think this below should add lambda function to API endpoint - but it does not work.

  # integration_uri  = aws_lambda_function.result_lambda_backend.invoke_arn
  integration_uri = "${aws_lambda_function.result_lambda_backend.arn}"
  integration_type = "AWS_PROXY"
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_route" "result_route" {
  api_id    = aws_apigatewayv2_api.main_apigateway.id
  route_key = "GET /results"
  target    = "integrations/${aws_apigatewayv2_integration.result_integration.id}"
}

resource "aws_lambda_permission" "result_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.result_lambda_backend.function_name
  principal     = "apigateway.amazonaws.com"

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

When looking into apigateway routes and integration it does have corresponding connected lambda "result" backend function. The "/result" lambda backend function is also created via TF code:

resource "aws_iam_role" "result_lambda_iam_role" {
  name               = "result_iam_role"
  assume_role_policy = <<EOF
{
 "Version": "2012-10-17",
 "Statement": [
   {
     "Action": "sts:AssumeRole",
     "Principal": {
       "Service": "lambda.amazonaws.com"
     },
     "Effect": "Allow",
     "Sid": ""
   }
 ]
}
EOF
}

resource "aws_iam_policy" "result_log_policy" {

  name   = "result_log_policy"
  policy = <<EOF
{
 "Version": "2012-10-17",
 "Statement": [
   {
     "Action": [
       "logs:CreateLogGroup",
       "logs:CreateLogStream",
       "logs:PutLogEvents"
     ],
     "Resource": "arn:aws:logs:*:*:*",
     "Effect": "Allow"
   }
 ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "attach_result_log_policy_to_iam_role" {
  role       = aws_iam_role.result_lambda_iam_role.name
  policy_arn = aws_iam_policy.result_log_policy.arn
}


resource "aws_iam_policy" "result_dynamodb_get_item_policy" {

  name   = "result_dynamodb_get_item_policy"
  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "dynamodb:DeleteItem",
                "dynamodb:GetShardIterator",
                "dynamodb:GetItem",
                "dynamodb:DescribeStream",
                "dynamodb:GetRecords"
            ],
            "Resource": "${aws_dynamodb_table.dynamodb_table_votes.arn}/Votes"
        }
    ]
}
EOF
}



resource "aws_iam_role_policy_attachment" "attach_result_dynamodb_get_item_policy" {
  role       = aws_iam_role.result_lambda_iam_role.name
  policy_arn = aws_iam_policy.result_dynamodb_get_item_policy.arn
}



data "archive_file" "result_zip_code" {
  type        = "zip"
  source_file = "${path.module}/result.py"
  output_path = "${path.module}/result.zip"
}


resource "aws_lambda_function" "result_lambda_backend" {
  filename      = "${path.module}/result.zip"
  function_name = "results"
  role          = aws_iam_role.result_lambda_iam_role.arn
  handler       = "result.lambda_handler"
  runtime       = "python3.9"

}

Why does it not add "/results" to API endpoint in lambda AWS console, what am I doing wrong?

2 Answers 2

1

You are using

name        = "$default"

change it to result and you will get /result at the end of the url

name        = "result"
Sign up to request clarification or add additional context in comments.

2 Comments

i changed to "result" and it does produce the correct endpoint, but another manually created apigateway still has stage=default and has "results" attached. there should be one stage (like in the old manually created apigateway - $default). this is kinda not exactly what i wanted.
yes, actually this change is wrong, since for another lambda function it also adds "results" to the endpoint, while it should have its own "/voting". i checked my 2nd function "voting" and it has wrong api endpoint pointing to "/results"
0

Apparently the thing responsible is "resource_path" arg. It's not available in Terraform. So the way to do this is to add function name at the end of API endpoint manually (last line):

resource "aws_lambda_permission" "vote_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.vote_lambda_backend.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn = "${aws_apigatewayv2_api.main_apigateway.execution_arn}/*/*/results"
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.