7
votes

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!

2
Did you resolve this issue?Kwhitejr

2 Answers

1
votes

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}"
}
-1
votes

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