Skip to content

Commit

Permalink
Add AWS Lambda support (#1127)
Browse files Browse the repository at this point in the history
This adds the lambda-web crate to adapt the actix App to speak to Lambda
by way of the lambda_runtime crate.

AWS Lambda has native support for scripting languages to
execute a function directly; compiled languages must embed a runtime to
fetch incoming events from Lambda and post the responses. This detects
the environment variables to start up in Lambda mode instead of the
normal HTTP server, and is added as an optional feature.

Lambda has five (!) distinct ways of routing HTTP requests to a
function; this supports some of them. (Specifically, the most obvious
way to do this is with a Function URL, which is newest and simplest, and
perhaps with CloudFront, which speaks to the Function URL and not Lambda
directly.)

The error handling could probably be refined, I was just trying to get
this to compile.

(Supported: API Gateway HTTP API with payload format version 2.0; API
Gateway REST API; Lambda function URLs / Not supported: API Gateway HTTP
API with payload format version 1.0; Application Load Balancer)

Necessary for #1102 to be able to run the released packages directly,
and only having to configure the appropriate environment.

---------

Co-authored-by: Yuri Astrakhan <[email protected]>
  • Loading branch information
jleedev and nyurik authored Feb 1, 2024
1 parent 3549d99 commit 9f9f181
Show file tree
Hide file tree
Showing 19 changed files with 408 additions and 61 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ pg_data/
config.yml
tests/output/
tmp/
.aws-sam/
2 changes: 2 additions & 0 deletions .github/files/lambda-function/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build-MartinFunction:
cp -a . $(ARTIFACTS_DIR)
3 changes: 3 additions & 0 deletions .github/files/lambda-function/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pmtiles:
sources:
webp2: ./webp2.pmtiles
3 changes: 3 additions & 0 deletions .github/files/lambda-layer/bootstrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
set -eu
exec martin -c "${_HANDLER}"
19 changes: 19 additions & 0 deletions .github/files/lambda.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This is a minimal AWS SAM template sufficient to invoke the handler
# in the CI environment. It probably hasn't been tested for actual
# deployments.

AWSTemplateFormatVersion: 2010-09-09
Transform: 'AWS::Serverless-2016-10-31'
Resources:
MartinLayer:
Type: 'AWS::Serverless::LayerVersion'
Properties:
ContentUri: lambda-layer/
MartinFunction:
Type: 'AWS::Serverless::Function'
Properties:
Runtime: provided.al2023
Layers:
- Ref: MartinLayer
CodeUri: lambda-function/
Handler: config.yaml
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ jobs:
with:
install: true
platforms: linux/amd64,linux/arm64
- name: Set up AWS SAM
uses: aws-actions/setup-sam@v2
with:
use-installer: true

- name: Build targets
run: |
Expand Down Expand Up @@ -177,6 +181,7 @@ jobs:
load: true
tags: ${{ github.repository }}:linux-arm64
platforms: linux/arm64

- name: Test linux/arm64 Docker image
run: |
PLATFORM=linux/arm64
Expand Down Expand Up @@ -288,6 +293,22 @@ jobs:
name: build-${{ matrix.target }}
path: target_releases/*

test-aws-lambda:
name: Test AWS Lambda
runs-on: ubuntu-latest
needs: [ build ]
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Download build artifact cross-build
uses: actions/download-artifact@v3
with:
name: cross-build
- run: tests/test-aws-lambda.sh
env:
MARTIN_BIN: x86_64-unknown-linux-musl/martin


test-multi-os:
name: Test on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ pg_data/
config.yml
tests/output/
tmp/
.aws-sam/
139 changes: 129 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ indoc = "2"
insta = "1"
itertools = "0.12"
json-patch = "1.2"
lambda-web = { version = "0.2.1", features = ["actix4"] }
log = "0.4"
martin-tile-utils = { path = "./martin-tile-utils", version = "0.4.0" }
mbtiles = { path = "./mbtiles", version = "0.9.0" }
Expand Down
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Running with Docker](run-with-docker.md)
- [Running with Docker Compose](run-with-docker-compose.md)
- [Running with NGINX](run-with-nginx.md)
- [Running in AWS Lambda](run-with-lambda.md)
- [Troubleshooting](troubleshooting.md)
- [Configuration File](config-file.md)
- [PostgreSQL Connections](pg-connections.md)
Expand Down
1 change: 1 addition & 0 deletions docs/src/env-vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ You can also configure Martin using environment variables, but only if the confi
| `PGSSLCERT` <br/> `ssl_cert` | `./postgresql.crt` | A file with a client SSL certificate. [docs](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-SSLCERT) |
| `PGSSLKEY` <br/> `ssl_key` | `./postgresql.key` | A file with the key for the client SSL certificate. [docs](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-SSLKEY) |
| `PGSSLROOTCERT` <br/> `ssl_root_cert` | `./root.crt` | A file with trusted root certificate(s). The file should contain a sequence of PEM-formatted CA certificates. [docs](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-SSLROOTCERT) |
| `AWS_LAMBDA_RUNTIME_API` | | If defined, connect to AWS Lambda to handle requests. The regular HTTP server is not used. See [Running in AWS Lambda](run-with-lambda.md) |
Loading

0 comments on commit 9f9f181

Please sign in to comment.