7

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

1 Answer 1

4

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"
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I had to use the format "arn:aws:lambda:${var.region}:${local.account_id}:function:$${stageVariables.lambda_function}" but otherwise it seems to work fine :)

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.