Deploying your Swift code on AWS Lambda

About a month ago, it became possible to run Swift code on AWS Lambda. I was really interesting to try and see how easy it would be to deploy small Swift functions as serverless application. Let’s see how.

If you missed the news, Swift code running on AWS Lambda is available under couple conditions, but first how does it work?

In short, it’s a Swift Package Manager project that is executed on AWS Lambda. Code wise, it’s really straightforward, a closure is executed when hitting the api. The library does the heavy lifting for you.

import AWSLambdaRuntime

Lambda.run { (...) in
    // some code here
}

Implementing Codable protocol allow you to enrich the input and output to encode and decode JSON content.

import AWSLambdaRuntime

// Using Codable for JSON encoding
private struct Input: Codable {
  let age: Int
}

// Using Codable for JSON encoding
private struct Output: Codable {
  let message: String
}

// Using Input and Output through callback
Lambda.run { (context, input: Input, callback: @escaping (Result<Output, Error>) -> Void) in
  guard input.age >= 18 else {
    callback(.success(Output(message: "Sorry, no kids allowed!")))
    return
  }
  callback(.success(Output(message: "Adulting is serious business.")))
}

Regarding the code itself, that’s about it. Pretty nice, right?

It gets a bit more tricky about the enviroment requirement to run and deploy your code. Since it’s not your usual iOS application, we need to create an Swift Package Manager executable for it and includes the right dependencies.

Make sure you have the latest Xcode version available, or at least Xcode 11.5. I’ve ran into a lot of issues with Xcode 11.3 to synchronize dependencies and make the executable work.

import PackageDescription

let package = Package(
    name: "MyLambdaFunction",
    platforms: [
        .macOS(.v10_13),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "0.1.0"),
    ],
    ...

Once your package is ready to be tested, you can execute it locally using environment variable LOCAL_LAMBDA_SERVER_ENABLED to true in the running scheme. This allows you to run it on your own machine, the server will listen to your localhost for any request.

From there, you can use curl commands or any api client and hit http://127.0.0.1:7000/invoke with your input to see if it works as expected.

The last step is to deploy in on AWS Lambda. This, to me, is where it became challenging. AWS Lambda runs on Linux environment, so you can’t just assume it’s gonna work just fine. We have to use a Docker image with Linux and Swift on it to create our final executable which will be deployed on AWS.

If you’re familiar with Docker, that it’s not much of a challenge, but if you’re not, like me, you’ve got couple requirements to cover as well. My advise is to follow thoroughly Fabian’s blog for this. He explains it very well each steps.

Once you’ve got your executable, you’ll need to upload it on AWS and create tests to start using it.


Overall, running Swift on AWS Lambda extends possibilities to serverless application that is really exciting. Once you figure out the dependency management steps, it’s really easy to use and test locally. The support of environment variables shows the developers effort to make it easy for the community. This is really appreciated.

On the other hand, it comes with some limitations. To me, the main one is the platform for execution: you won’t be able to use some really nice frameworks that are only available on Apple devices: I wanted to use CoreML with AWS Lambda and was stopped really quickly.

The second limitation I want to highlight is performance: if Swift is pretty fast, the cold start on AWS Lambda felt slow, or slower than competition like Go or Node Js. It can come from my code, but it’s worth checking if it’s the right tool long term for your project.

Regardless, being able to use Swift code for serverless application and only based on Swift Package Manager is really promising. It’s quite different that my usual iOS development and forced me to rethink of code implementation, something I really enjoyed.

Thanks for reading πŸš€

© 2020 Benoit Pasquier. All Rights Reserved
Author's picture

Benoit Pasquier

iOS Software engineer πŸ‡«πŸ‡·, writing about Swift, Data and more.

ShopBack πŸ’°

Singapore πŸ‡ΈπŸ‡¬