A Varnish VMOD for invoking AWS Lambda functions from VCL. Built using varnish-rs and the AWS SDK.
This VMOD allows Varnish to invoke AWS Lambda functions directly, and exposes them as backends.
cargo build --releasecargo testThe VMOD uses the standard AWS SDK credential chain:
- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY) - EC2 instance IAM role
- ECS task IAM role
- Shared credentials file (
~/.aws/credentials)
No explicit credential configuration is needed if running on AWS infrastructure with IAM roles.
import lambda;
sub vcl_init {
new fn = lambda.backend(
function_name="my-lambda-function",
region="us-east-1"
);
}
sub vcl_recv {
# Invoke Lambda with a JSON payload
set req.http.X-Lambda-Response = fn.invoke(
"{\"url\": \"https://example.com\", \"viewport\": \"1920x1080\"}"
);
return (synth(200));
}Use Lambda as a Varnish backend to proxy HTTP requests:
import lambda;
# Note that you pay for these lambda invocations, so make health check
# fast and adjust interval accordingly
probe lambda_probe {
.url = "/ok";
.timeout = 3s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
sub vcl_init {
new my_lambda = lambda.backend(
function_name="my-lambda",
region="us-east-2",
probe=lambda_probe
);
}
sub vcl_backend_fetch {
set bereq.backend = my_lambda.backend();
}Creates a new Lambda backend object.
Parameters:
function_name(STRING, required): Lambda function name or ARNregion(STRING, required): AWS region (e.g., "us-east-1", "eu-west-1")endpoint_url(STRING, optional): Custom endpoint URL (e.g., for LocalStack)timeout(DURATION, optional): Lambda invocation timeout in seconds (default: 62s)probe(PROBE, optional): Health probe configurationresponse_format(STRING, optional): Response format - "json" (default) or "http" (C++ runtime only)
Returns: Backend object
Example:
sub vcl_init {
new my_function = lambda.backend(
function_name="my-function",
region="us-east-1",
timeout=30s
);
}Invokes the Lambda function with a payload.
Parameters:
payload(STRING): JSON payload to send to Lambda
Returns: STRING - Response body from Lambda
Example:
set req.http.X-Response = my_function.invoke('{"key": "value"}');Note: This is a synchronous invocation (RequestResponse type). The VCL execution blocks until Lambda returns or times out.
Returns the Lambda function name.
Returns: STRING
Returns the AWS region.
Returns: STRING
Returns a VCL backend that can be used with set bereq.backend for proxying HTTP requests through Lambda.
Returns: VCL_BACKEND
Example:
sub vcl_backend_fetch {
set bereq.backend = my_lambda.backend();
}The VMOD uses a Tokio runtime in the background to handle concurrent Lambda invocations:
- Single Tokio runtime per VCL load
- Unbounded MPSC channel for request queueing
- Each Lambda invocation runs as a separate async task
- VCL threads block on oneshot channels waiting for responses
Lambda functions have a maximum timeout of 15 minutes. However, synchronous invocations should complete much faster (typically < 30 seconds) to avoid blocking Varnish worker threads.
AWS Lambda has some important limits to know about:
- Maximum synchronous payload: 6 MB
- Maximum response size: 6 MB
- Rust 1.91+
- Varnish 7.7+
- AWS credentials configured
BSD-3-Clause