Setting Up an API Gateway with a Lambda Integration
This guide explains how to expose a Lambda function via API Gateway (HTTP API) using the terraform-byks-module.
Step 1: Define your Lambda function
See the Lambda documentation for further details
Add an entry to lambda_functions. The map key (kattehotell-api) becomes the Lambda's logical ID inside the module.
module "application" {
...
lambda_functions = {
kattehotell-api = {
package_type = "Image"
ecr_uri = local.ecr["kattehotell-api] # or 336385411112.dkr.ecr.eu-west-1.amazonaws.com/kattehotell-api-shared
image_tag = var.environment # usually dev,test,prod
environment_variables = {
LOG_LEVEL = "info"
}
}
}
}
...
Step 2: Define the API Gateway
Set api_gateway and point an integration at the Lambda you defined above. The integration key (kattehotell-api-integration) is a name you choose, and is only used internally to link to a route.
module "application" {
...
api_gateway = {
description = "Public API for my application"
integrations = {
lambda_functions = {
# Key = integration name, referenced by routes below
kattehotell-api-integration = {
lambda_function_id = "kattehotell-api" # Must match a key in lambda_functions
description = "kattehotell-api handler"
integration_method = "POST" # Lambda proxy always uses POST internally
timeout_milliseconds = 30000
payload_format_version = "2.0" # 2.0 is recommended for HTTP API
}
}
}
routes = {
# Key format: "METHOD /path"
"GET /cats" = {
target_integration = "kattehotell-api-integration" # Must match an integration key above
authorizer = "onelogin" # Check step 3 for setting up an authorizer, 'NONE' is also valid input, but not recommended
}
"POST /cats" = {
target_integration = "kattehotell-api-integration"
authorizer = "onelogin" # Check step 3 for setting up an authorizer, 'NONE' is also valid input, but not recommended
}
}
}
...
}
The resulting public URL is:
-
https://kattehotell-api.dev.bymoslo.net/cats(DEV) -
https://kattehotell-api.test.bymoslo.net/cats(TEST) -
https://kattehotell-api.bymoslo.no/cats(PROD)
Step 3: (optional) Protect routes with a JWT authorizer
Add an authorizer block and reference it by name in any route that should require authentication.
module "application" {
...
api_gateway = {
authorizers = {
onelogin = {
identity_sources = ["$request.header.Authorization"]
jwt_configuration = {
issuer = <onelogin_issuer> # Issuer URL depends on environment, usually https://oslo.onelogin.com/oidc/2 (PROD) or https://sandbox-oslo.onelogin.com/oidc/2 (TEST/DEV)
audience = ["<my-app-client-id>"]
}
}
}
integrations = {
lambda_functions = {
kattehotell-api-integration = {
lambda_function_id = "kattehotell-api"
}
}
}
routes = {
"GET /cats" = {
target_integration = "kattehotell-api-integration"
authorizer = "onelogin" # Name of the authorizer above
authorization_scopes = ["openid", "profile"] # Only applicable for JWT authorizers
}
}
}
...
}
Step 4: (optional) Enable CORS
CORS Configuration
Exact configuration of CORS (origins, methods, headers) varies depending on what is required by the backend API
module "application" {
...
api_gateway = {
cors_configuration = {
allow_origins = ["https://kattehotell-frontend.dev.bymoslo.net", "https://localhost:3000", "http://localhost:3000"] # Eksempel-URL, localhost
allow_methods = ["*"]
allow_headers = ["*"]
max_age = 300
}
# ... integrations and routes as above
}
}
...
Complete minimal example
locals {
ecr = { for k, v in data.terraform_remote_state.shared_kattehotell_ecr.outputs.ecr: k => v.ecr_url }
}
module "application" {
source = "git@github.com:BYM-IKT/terraform-byks-module.git?ref=v12"
account_id = var.account_id
region = var.region
application_name = "kattehotell-api"
environment = var.environment
team = var.team
lambda_functions = {
kattehotell-api = {
ecr_uri = "336385411112.dkr.ecr.eu-west-1.amazonaws.com/kattehotell-api-shared"
image_tag = var.environment
}
}
api_gateway = {
description = "API gateway for kattehotell-løsningen"
integrations = {
lambda_functions = {
kattehotell-api-integration = {
lambda_function_id = "kattehotell-api"
}
}
}
authorizers = {
onelogin = {
identity_sources = ["$request.header.Authorization"]
jwt_configuration = {
issuer = "https://sandbox-oslo.onelogin.com/oidc/2" # Issuer URL depends on environment, usually https://oslo.onelogin.com/oidc/2 (PROD) or https://sandbox-oslo.onelogin.com/oidc/2 (TEST/DEV)
audience = ["kattehotell-client-id"]
}
}
}
routes = {
"GET /cats" = {
target_integration = "kattehotell-api-integration"
authorizer = "onelogin"
}
}
}
providers = {
aws.route53 = aws.route53
aws.us-east-1 = aws.us-east-1
aws.ses = aws.ses
}
}