11

I'm writing Terraform to deploy an AWS API Gateway with AWS Lambda integration. I would like to specify an optional path parameter in the url that I can reference from the lambda. I can't figure out how to specify this in the AWS API Gateway terraform.

The only information I can find for path variables is this SO post: In Terraform, how do you specify an API Gateway endpoint with a variable in the request path?

In it, the answer specifies the path variable in the uri field of the aws_api_gateway_integration function:

resource "aws_api_gateway_integration" "get-account-integration" {
    rest_api_id             = "${var.gateway_id}"
    resource_id             = "${var.resource_id}"
    http_method             = "${aws_api_gateway_method.get-account.http_method}"
    type                    = "HTTP"
    integration_http_method = "GET"
    uri                     = "/integration/accounts/{id}" # <--
    passthrough_behavior    = "WHEN_NO_MATCH"

    request_parameters {
        "integration.request.path.id" = "method.request.path.accountId"
    }
}

Unfortunately, with AWS Lambda integration uses that uri field for the ARN of the lambda. Here is how I reference the lambda in my integration:

resource "aws_api_gateway_integration" "books_lambda" {
  rest_api_id             = "${var.gateway.id}"
  resource_id             = "${var.resource_id}"
  http_method             = "${aws_api_gateway_method.books.http_method}"
  type                    = "AWS_PROXY"
  integration_http_method = "POST"
  uri                     = "${var.books_invoke_arn}" # <--
  credentials             = "${aws_iam_role.books_gateway.arn}"

  request_parameters {
    "integration.request.path.id" = "method.request.path.bookId"
  }
}

Because the arn is in the place of the uri field, I don't know where to define the placement of the path parameter.

I've tried appending the path variable to the uri field (${var.books_invoke_arn}/{bookId}), but it just creates an error. Where can I specify the path variable when the uri field is occupied by the lambda arn?

Second, is it possible to make that variable optional, or would I have to have a second set of terraform (one with the variable, one without)?

Thanks!

user2233394
  • 155
  • 1
  • 7

3 Answers3

2

This is an old question, but it came up in one of my searches. I think that things may have changed in the interim but a way to do this currently is by specifying your variable in curly braces in the route_key as in this example from our code:

resource "aws_apigatewayv2_route" "room-recommendations-ng" {
  api_id             = aws_apigatewayv2_api.this.id
  route_key          = "GET /rooms/{room}/recommendations"
  target             = "integrations/${aws_apigatewayv2_integration.room-recommendations.id}"
}
Cargo23
  • 3,064
  • 16
  • 25
0

Since type is AWS_PROXY, the URI must be a fully formed, encoded HTTP(S) URL according to the RFC-3986 specification . For AWS integrations, the URI should be of the form arn:aws:apigateway:{region}:{subdomain.service|service}:{path|action}/{service_api}.

Try the following code (I assumed us-east-1 region):

resource "aws_api_gateway_integration" "books_lambda" {
  rest_api_id             = var.gateway.id
  resource_id             = var.resource_id
  http_method             = aws_api_gateway_method.books.http_method
  type                    = "AWS_PROXY"
  integration_http_method = "POST"
  uri                     = "arn:aws:apigateway:us-east-1:lambda:path/integration/accounts/{id}"
  credentials             = aws_iam_role.books_gateway.arn

  request_parameters      = {
    "integration.request.path.id" = "method.request.path.bookId"
  }
}

For additional information see Resource: aws_api_gateway_integration

Saeed D.
  • 1,125
  • 1
  • 11
  • 23
-1

The terraform document gives the answer already.

resource "aws_api_gateway_integration" "integration" {
  rest_api_id             = "${aws_api_gateway_rest_api.api.id}"
  resource_id             = "${aws_api_gateway_resource.resource.id}"
  http_method             = "${aws_api_gateway_method.method.http_method}"
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = "arn:aws:apigateway:${var.myregion}:lambda:path/2015-03-31/functions/${aws_lambda_function.lambda.arn}/invocations"
}

For your second question, I need details, for current description, you can think to use count to manage it.

Reference:

https://www.terraform.io/intro/examples/count.html

https://www.terraform.io/docs/configuration/resources.html#count-multiple-resource-instances

Update

Since you don't paste the code on how to manage the lambda function. If you do manage it, you can reference it as ${aws_lambda_function.lambda.arn}

resource "aws_lambda_function" "lambda" {
  filename      = "lambda_function_payload.zip"
  function_name = "lambda_function_name"
  ...
}

If the lambda function is exist, you can get its detail via its data source

data "aws_lambda_function" "existing_lambda" {
  function_name = "${var.function_name}"
}

You can reference it as data.aws_lambda_function.existing_lambda.arn

BMW
  • 42,880
  • 12
  • 99
  • 116
  • Thank you for the response, BMW. I've spend a lot of time with the terraform document that you link, but I don't see the answer. Are you saying that the path parameter needs to be a part of the lambda arn? If so, where in the arn should I place the path parameter? – user2233394 Jun 14 '19 at 16:12
  • Thank you for taking the time to update your answer, but I believe we have some confusion between us. I am able to reference the lambda without a problem. I export the lambda arn from my lambda terraform, and plug that into the uri field of the aws_api_gateway_integration (you can see my code in the second code block above). What it unclear is how to specify a path parameter in the integration terraform above. The uri field is generally the place for that, but since the uri field has the lambda arn, I don't know how or where to specify the placement of the path parameter. – user2233394 Jun 15 '19 at 06:11
  • 1
    @user2233394 you only need to add the lamba arn and not the path itself. You don't need to add the mapping in request_parameters in the integration setup either. Once you have the path parameters set up through resources, they'll appear in your Lambda event as `pathParameters`. – user2980055 Jun 18 '19 at 14:48