2

I'm trying to deploy a basic API consisting in a lambda function as main endpoint and API gateway as proxy to this function. With the following configuration i'm able to build up the infrastructure, but I cannot set to trigger the lambda function through IaC, I have to go to the AWS console in order to manually set the trigger.

resource "aws_lambda_function" "main_endpoint_function" {
  function_name = "main_endpoint_function"


  s3_bucket = module.s3.function_bucket_name
  s3_key = "index.zip"


  handler = "index.handler"
  runtime = var.runtime_handler

  role = aws_iam_role.lambda_role.arn
}

resource "aws_iam_role" "lambda_role" {
  name = "role_lambda_test"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}
//lambda has to be manually triggered from api gateway
resource "aws_api_gateway_rest_api" "apiLambda" {
  name        = "myAPI"
  description = "terraform test"
}

resource "aws_api_gateway_resource" "proxy" {
   rest_api_id = aws_api_gateway_rest_api.apiLambda.id
   parent_id   = aws_api_gateway_rest_api.apiLambda.root_resource_id
   path_part   = "{proxy+}"
}

resource "aws_api_gateway_method" "proxyMethod" {
   rest_api_id   = aws_api_gateway_rest_api.apiLambda.id
   resource_id   = aws_api_gateway_resource.proxy.id
   http_method   = "ANY"
   authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda" {
   rest_api_id = aws_api_gateway_rest_api.apiLambda.id
   resource_id = aws_api_gateway_method.proxyMethod.resource_id
   http_method = aws_api_gateway_method.proxyMethod.http_method

   integration_http_method = "POST"
   type                    = "AWS_PROXY"
   uri                     = aws_lambda_function.main_endpoint_function.invoke_arn
}

resource "aws_api_gateway_method" "proxy_root" {
   rest_api_id   = aws_api_gateway_rest_api.apiLambda.id
   resource_id   = aws_api_gateway_rest_api.apiLambda.root_resource_id
   http_method   = "ANY"
   authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_root" {
   rest_api_id = aws_api_gateway_rest_api.apiLambda.id
   resource_id = aws_api_gateway_method.proxy_root.resource_id
   http_method = aws_api_gateway_method.proxy_root.http_method

   integration_http_method = "POST"
   type                    = "AWS_PROXY"
   uri                     = aws_lambda_function.main_endpoint_function.invoke_arn
}

resource "aws_api_gateway_deployment" "apideploy" {
   depends_on = [
     aws_api_gateway_integration.lambda,
     aws_api_gateway_integration.lambda_root,
   ]

   rest_api_id = aws_api_gateway_rest_api.apiLambda.id
   stage_name  = "test"
}


Without the manually set trigger through the console I get Internal Server Error. With triggering functions correctly. Perhaps there is something wrong with my configuration ?

Update::

After adding the permission resources for Lambda and API Gateway I also created aws_api_gateway_method_response and aws_api_gateway_integration_response. On first run errors, on second run completes. I tried adding explicit implications but they didn't solve the issue..

resource "aws_api_gateway_method_response" "response_200" {
  rest_api_id = aws_api_gateway_rest_api.apiLambda.id
  resource_id = aws_api_gateway_resource.proxy.id
  http_method = aws_api_gateway_method.proxy_root.http_method
  status_code = "200"
  depends_on = [
    aws_api_gateway_rest_api.apiLambda,
    aws_api_gateway_resource.proxy,
    aws_api_gateway_method.proxy_root
  ]
}

resource "aws_api_gateway_integration_response" "MyDemoIntegrationResponse" {
  rest_api_id = aws_api_gateway_rest_api.apiLambda.id
  resource_id = aws_api_gateway_resource.proxy.id
  http_method = aws_api_gateway_method.proxy_root.http_method
  status_code = aws_api_gateway_method_response.response_200.status_code
  depends_on = [
    aws_api_gateway_rest_api.apiLambda,
    aws_api_gateway_resource.proxy,
    aws_api_gateway_method.proxy_root,
    aws_api_gateway_method_response.response_200
  ]

  # Transforms the backend JSON response to XML
  response_templates = {
    "application/xml" = <<EOF
#set($inputRoot = $input.path('$'))
<?xml version="1.0" encoding="UTF-8"?>
<message>
    $inputRoot.body
</message>
EOF
  }
}

the Error is: │ Error: Error creating API Gateway Method Response: NotFoundException: Invalid Method identifier specified │ │ with aws_api_gateway_method_response.response_200, │ on main.tf line 130, in resource "aws_api_gateway_method_response" "response_200": │ 130: resource "aws_api_gateway_method_response" "response_200" {

1
  • Can you drop the depends_on form the method that is failing? Commented Apr 8, 2022 at 11:39

1 Answer 1

4

It seems you are missing the aws_lambda_permission resource [1]. In your case, you would need to add the following (similar to example from the reference):

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

  source_arn = "arn:aws:execute-api:${var.myregion}:${var.accountId}:${aws_api_gateway_rest_api.apiLambda.id}/*/${aws_api_gateway_method.proxyMethod.http_method}${aws_api_gateway_resource.proxy.path}"
}

Since I don't know which region and account you are using (I don't need to know that), you just have to replace the var.myregion with the API Gateway region and var.accountId with the AWS account where the API Gateway is created. You can achieve that by using data sources. In theory, you might as well leave out the method reference from the source_arn and use something like:

source_arn = "arn:aws:execute-api:${var.myregion}:${var.accountId}:${aws_api_gateway_rest_api.apiLambda.id}/*/*/*"

I have removed the second reference from the code and it is now referenced in [2].


[1] https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_integration#lambda-integration

[2] http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for the reply. I've added lambda and api_gateway permissions, next issue was response integration to which I added the appropriate resource aws_api_gateway_method_response and integrated it with aws_api_gateway_integration_response and still get errors for some reason. I'll update the post..
I would say that is a different issue compared to the original one.
I totally agree
I meant to say it should be a different question, as this helped you resolve the original issue. :)

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.