Skip to main content

Serverless

Intro

To run IGUHealth in a serverless environment we recommend using the servless-http wrapper. Install @iguhealth/server via npm and use the following code as the entry point to your handler.

import serverless from "serverless-http";

import createServer from "@iguhealth/server";

const server = await createServer();
const handler = serverless(server);
export { handler };

AWS Lambda

With AWS Lambda you can provision a lambda function for server and route requests to it via AWS API Gateway. Below is an example configuration that could set this up.


resource "aws_s3_object" "lambda" {
bucket = aws_s3_bucket.lambda_bucket.id

key = "source.zip"
source = "${path.root}/iguhealth-lambda-server.zip"

metadata = {
hash = data.external.worker_zip.result.hash
}
depends_on = [null_resource.my_lambda_buildstep]

}

resource "aws_lambda_function" "iguhealth_server" {
function_name = "iguhealth_server-${random_string.random.id}"

publish = true
s3_bucket = aws_s3_bucket.lambda_bucket.id
s3_key = aws_s3_object.lambda.key

memory_size = 512

runtime = "nodejs18.x"
handler = "iguhealth-lambda-server/src/index.handler"

source_code_hash = data.external.worker_zip.result.hash

description = "IGUHEALTH Lambda server"

role = aws_iam_role.lambda_exec.arn
timeout = 60

vpc_config {
subnet_ids = var.vpc_subnets
security_group_ids = [var.security_group]
}

environment {
variables = var.server_environment
}
}

###############################################################
# API Gateway
###############################################################

resource "aws_apigatewayv2_api" "this" {
name = "apigw-http-lambda-rds-proxy-${random_string.random.id}"
protocol_type = "HTTP"
}

resource "aws_cloudwatch_log_group" "api_gw" {
name = "/aws/api_gw/${aws_apigatewayv2_api.this.name}"

retention_in_days = var.lambda_log_retention
}

resource "aws_apigatewayv2_stage" "lambda" {
api_id = aws_apigatewayv2_api.this.id

name = "$default"
auto_deploy = true

access_log_settings {
destination_arn = aws_cloudwatch_log_group.api_gw.arn

format = jsonencode({
requestId = "$context.requestId"
sourceIp = "$context.identity.sourceIp"
requestTime = "$context.requestTime"
protocol = "$context.protocol"
httpMethod = "$context.httpMethod"
resourcePath = "$context.resourcePath"
routeKey = "$context.routeKey"
status = "$context.status"
responseLength = "$context.responseLength"
integrationErrorMessage = "$context.integrationErrorMessage"
}
)
}
}

resource "aws_apigatewayv2_integration" "lambda" {
api_id = aws_apigatewayv2_api.this.id

integration_uri = aws_lambda_function.iguhealth_server.invoke_arn
integration_type = "AWS_PROXY"
integration_method = "POST"
}

resource "aws_apigatewayv2_route" "any" {
api_id = aws_apigatewayv2_api.this.id

route_key = "$default"
target = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}

resource "aws_lambda_permission" "api_gw" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.iguhealth_server.function_name
principal = "apigateway.amazonaws.com"

source_arn = "${aws_apigatewayv2_api.this.execution_arn}/*/*"
}