Build and deploy Swift Package Manager projects on AWS Lambda.
swift lambda
builds Swift projects using the
Swift AWS Lambda Runtime
for deployment into
AWS Lambda
functions.
It uses a Swift
cross compilation toolchain
for
Amazon Linux
to build the project right on macOS, no Docker required.
Simply call swift lambda build
.
A built Swift lambda can then be deployed using swift lambda deploy
(using either aws lambda publish
or sam deploy
).
Blog article: Deploying Swift on AWS Lambda.
Note: Requires a Swift 5.3 install (e.g. Xcode 12+).
First make sure swift --version
shows a 5.3 release, it is currently required.
swift lambda
is easiest to install using Homebrew,
get it over here.
This single call installs swift lambda
and all its dependencies:
$ brew install SPMDestinations/tap/swift-lambda
It's a pretty big download at over 1GB (binary host & target Swift toolchains from Swift.org and the AWS CLI).
A simple Swift Lambda using Macro.
Setup the Swift package:
mkdir HelloWorld && cd HelloWorld
swift package init --type executable
open Package.swift # opens Xcode
Configure the Package.swift
to look like this:
// swift-tools-version:5.2
import PackageDescription
let package = Package(
name : "HelloWorld",
platforms : [ .macOS(.v10_13) ], // <== add this
dependencies : [ // and add this dependency ↓
.package(url: "https://github.com/Macro-swift/MacroLambda.git",
from: "0.1.3"),
.package(url: "https://github.com/AlwaysRightInstitute/cows.git",
from: "1.0.0") // optional but fun
],
targets: [
.target(name: "HelloWorld",
dependencies: [ "MacroLambda", "cows" ])
]
)
Fill in the Lambda's code in the main.swift
:
import MacroLambda
let app = Express()
app.use(bodyParser.text())
app.post("/hello") { req, res, next in
res.send("Client sent: \(req.body.text ?? "~nothing~")")
}
app.get { req, res, next in
res.send("Welcome to Macro!\n")
}
if process.isRunningInLambda {
Lambda.run(app)
}
else {
app.listen(1337) {
console.log("server running on http://localhost:1337/")
}
}
Build the package using swift lambda build
and deploy it to AWS by
calling swift lambda deploy
.
It expects a Lambda configuration called HelloWorld
(select a different
function using the -f
argument).
A more complex example: express-simple-lambda, it looks like this:
swift lambda build
$ swift lambda build -h
Unknown argument: -h
usage: swift lambda build [mode] [options]
Modes:
-c, --configuration debug|release [default: debug]
--clean build|dist [default: build]
Product:
-p, --product <product> [default: directory name]
-d, --destination <dest>
Options:
-v, --verbose
-s, --silent
--static
--static-libs <libs>
swift lambda deploy
$ swift lambda deploy -h
usage: swift lambda deploy [options]
-f, --function <name>
-p, --product <product>
-t, --template <SAM template> (optional)
--stack-name <SAM stackname> (optional)
If no function/product name is provided, the current directory
will be used.
Build Options:
--skip-build (do not invoke swift lambda build)
-c, --configuration debug|release [default: debug]
-d, --destination <dest>
--static
--static-libs <libs>
Options:
-v, --verbose
-s, --silent
Package.swift
(vs create a new tool project in Xcode).
We might address that and even provide a SwiftXcode style Lambda Xcode
template. Direct deployment from within Xcode should be possible.
(Issue 2)swift lambda build
has some support for static linking already builtin,
but it doesn't fully work yet. To be fixed.
(static linking reduces the size of the zip and further improves Lambda
startup time).
(Issue 3)swift-lambda is brought to you by ZeeZide. We like feedback, GitHub stars, cool contract work, presumably any form of praise you can think of.