Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify lambda function called by api gateway stage when using terraform?

I am trying to create IaC for an AWS API Gateway with two stages; development and production, with each stage invoking a different Lambda function.

I would like the end result to be:

  • If a user hits the development stage, they will invoke the development Lambda function
  • If a user hits the production stage, they will invoke the production Lambda function

My code currently looks like this, I've removed some resources that aren't relevant to the question:

resource "aws_apigatewayv2_api" "app_http_api_gateway" {
  name          = "app-http-api"
  protocol_type = "HTTP"
}

resource "aws_apigatewayv2_integration" "app_http_api_integration" {
  api_id                    = aws_apigatewayv2_api.app_http_api_gateway.id
  integration_type          = "AWS_PROXY"
  connection_type           = "INTERNET"
  description               = "Lambda integration"
  integration_method        = "POST"
  # Unsure how to apply stage_variables here
  integration_uri           = aws_lambda_function.app_lambda_development.invoke_arn
  passthrough_behavior      = "WHEN_NO_MATCH"
}

resource "aws_apigatewayv2_route" "app_http_api_gateway_resource_route" {
  api_id    = aws_apigatewayv2_api.app_http_api_gateway.id
  route_key = "ANY /{resource}"
  target    = "integrations/${aws_apigatewayv2_integration.app_http_api_integration.id}"
}

resource "aws_apigatewayv2_stage" "app_http_api_gateway_development" {
  api_id            = aws_apigatewayv2_api.app_http_api_gateway.id
  name              = "development"
  auto_deploy       = true
  stage_variables   = {
    lambda_function = aws_lambda_function.app_lambda_development.function_name
  }
}

resource "aws_apigatewayv2_stage" "app_http_api_gateway_production" {
  api_id            = aws_apigatewayv2_api.app_http_api_gateway.id
  name              = "production"
  auto_deploy       = true
  stage_variables   = {
    lambda_function = aws_lambda_function.app_lambda_production.function_name
  }
}

https://aws.amazon.com/blogs/compute/using-api-gateway-stage-variables-to-manage-lambda-functions

According to this page, I think it should be possible to achieve this.

I've added a stage_variable to define the Lambda function to use for each stage, however I'm unsure how to actually get this value into the integration, I assume it's done via the aws_apigatewayv2_integration / integration_uri setting, but I could not find any examples of stageVariables being used (only set) in the docs:

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/apigatewayv2_stage

Any advice appreciated

Thanks

like image 638
Dan Avatar asked Aug 09 '26 13:08

Dan


1 Answers

You're going to need to break down the invoke arn so that you can template it. API gateway uses a templating language that is obnoxiously similar to terraform's - both use ${expression}. To use API gateway stage variables in terraform, use double $$ to escape the dollar sign - so your statements will look like $${stageVariables.myVariableName}.

resource "aws_apigatewayv2_integration" "app_http_api_integration" {
api_id                    = aws_apigatewayv2_api.app_http_api_gateway.id
integration_type          = "AWS_PROXY"
connection_type           = "INTERNET"
description               = "Lambda integration"
integration_method        = "POST"
# Unsure how to apply stage_variables here
integration_uri           = "arn:aws:apigateway:${local.my_region}:lambda:path/2015-03-31/functions/$${stageVariables.lambda_name}/invocations"
passthrough_behavior      = "WHEN_NO_MATCH"
}
like image 62
Dan Monego Avatar answered Aug 12 '26 11:08

Dan Monego



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!