Skip to content

SWIFT-1536 Add AWS Lambda Example #771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Examples/AWSLambdaExample/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM swift:5.6-amazonlinux2
RUN yum -y install cmake openssl-devel cyrus-sasl-devel
28 changes: 28 additions & 0 deletions Examples/AWSLambdaExample/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "AWSLambdaExample",
platforms: [.macOS(.v12)],
dependencies: [
.package(
url: "https://github.com/swift-server/swift-aws-lambda-runtime.git",
branch: "main"
),
.package(
url: "https://github.com/mongodb/mongo-swift-driver",
.upToNextMajor(from: "1.0.0")
)
],
targets: [
.executableTarget(
name: "AWSLambdaExample",
dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
.product(name: "MongoSwift", package: "mongo-swift-driver")
]
),
]
)
46 changes: 46 additions & 0 deletions Examples/AWSLambdaExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# AWSLambdaExample

This is a minimal working example of using the driver in AWS Lambda.

## Building the example
The example code needs to be compiled for Amazon Linux 2 to be run in AWS Lambda.
You can use [Docker](https://docs.docker.com/desktop/) to achieve this.

First, run the following command to build a Docker image using the [`Dockerfile`](Dockerfile) in
this directory:
```
docker build -t swift-lambda .
```
This will install the dependencies necessary to build the driver on Linux.

Note that the `Dockerfile` uses Swift 5.6, the latest version at the time of writing. If you'd like
to use a different version, visit [DockerHub](https://hub.docker.com/_/swift) for a full list of
Swift Docker images.

Next, use the image you created to compile the example:
```
$ docker run \
--rm \
--volume "$(pwd)/:/src" \
--workdir "/src/" \
swift-lambda \
swift build --product AWSLambdaExample -c release -Xswiftc -static-stdlib
```

Finally, run the [`package.sh`](package.sh) script in this directory to create a symlink called
`bootstrap` and zip the folder:
```
./package.sh AWSLambdaExample
```
Navigate to the Code section on the page for your AWS Lambda function in the AWS Console and upload
the `lambda.zip` file created.

## Acknowledgements
The instructions for using Docker to build the example were largely taken from
[this blog post](https://fabianfett.dev/getting-started-with-swift-aws-lambda-runtime) by
Fabian Fett. Feel free to read through the post for more detailed information on the Docker
commands used.

The `package.sh` script is copied from
[this example](https://github.com/swift-server/swift-aws-lambda-runtime/blob/main/Examples/Deployment/scripts/package.sh)
in the `swift-aws-lambda-runtime` repository.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// begin lambda connection example 1
import AWSLambdaRuntime
import Foundation
import MongoSwift
import NIO

struct Input: Codable {
let number: Double
}

struct Response: Codable {
let ok: Double
}

@main
final class MongoHandler: LambdaHandler {
typealias Event = Input
typealias Output = Response

let elg: EventLoopGroup
let mongoClient: MongoClient

required init(context _: LambdaInitializationContext) async throws {
let uri = ProcessInfo.processInfo.environment["MONGODB_URI"] ?? "mongodb://localhost:27017"
self.elg = MultiThreadedEventLoopGroup(numberOfThreads: 4)
self.mongoClient = try MongoClient(uri, using: self.elg)
}

deinit {
// clean up driver resources
try? mongoClient.syncClose()
cleanupMongoSwift()

// shut down EventLoopGroup
try? elg.syncShutdownGracefully()
}

func handle(_: Event, context _: LambdaContext) async throws -> Output {
let db = self.mongoClient.db("db")
let response = try await db.runCommand(["ping": 1])
return try BSONDecoder().decode(Output.self, from: response)
}
}

// end lambda connection example 1
13 changes: 13 additions & 0 deletions Examples/AWSLambdaExample/package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

set -eu

executable=$1

target=.build/lambda/$executable
rm -rf "$target"
mkdir -p "$target"
cp ".build/release/$executable" "$target/"
cd "$target"
ln -s "$executable" "bootstrap"
zip --symlinks lambda.zip *
2 changes: 1 addition & 1 deletion etc/build-examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exit_code=0

examples=("BugReport" "Docs" "KituraExample" "PerfectExample" "VaporExample" "Atlas")
examples=("BugReport" "Docs" "KituraExample" "PerfectExample" "VaporExample" "Atlas" "AWSLambdaExample")

branch=${1}
# Ensure branch is non-empty
Expand Down