Azure Functions Swift support

I've been working on adding Swift Support to Azure Functions. The framework supports the most popular triggers and bindings like Http, Queue, Table, Blob & Service Bus. More bindings/triggers support will be added soon! Swift Azure Functions are deployable to been tested on Azure.
https://github.com/SalehAlbuga/azure-functions-swift
Despite being in an early stage, It's a fully functioning Serverless Swift project that supports a major cloud provider! Here is a getting started guid Writing an Azure Function, in Swift! | by Saleh | Medium
Any feedback is more than welcome! :smile:

21 Likes

Wow, this looks really cool. Thanks for putting this together. I've gotta try this after the holidays :slight_smile:.

Oh, and one more thing, I see you're using grpc-swift 1.0.0-alpha-X which is really awesome. If you don't mind, it'd be much appreciated if you could write about your experience with it in the SSWG gRPC proposal thread: [Discussion] gRPC Swift

1 Like

@johannesweiss please let me know if you tried using Azure Functions for Swift :smiley: I'd love to hear feedback on it!

1 Like

Minor: Instead of .init(rawValue: 0) for the option set, you can just write the nicer [].

2 Likes

run doesn't work for me:

helge@Zini18 FirstAzure $ swiftfunc run
Compiling Project.. 💻
Compiled!
Exporting hello
Project exported!

Exported! 

Starting host 🏠 


Fatal error: `execve` call returned that means failure.: file /private/tmp/swift-func-20200414-51067-evde5h/Sources/swiftfunc/BSD.swift, line 70
1 Like

@Helge_Hess1 Thank you for the feedback! Can you please provide me with the version of macOS you're using? Also I just want to confirm that Function Core Tools are installed

Ah, OK, I lack those. I was thinking your brew formula would pull in all dependencies. Tried this now:

  brew cask install dotnet-sdk
  brew install azure/functions/azure-functions-core-tools
  export FUNCTIONS_CORE_TOOLS_TELEMETRY_OPTOUT=1
  swiftfunc run

(why does the .NET SDK need root permissions? :scream:)

But now it seems to be hanging:

...
Azure Functions Core Tools (2.7.2254 Commit hash: ae06bd1a6012aa6a0859b5f30d3077947267d2b6)
Function Runtime Version: 2.0.13017.0
Item has already been added. Key in dictionary: 'TERM'  Key being added: 'TERM'

OK, an unset TERM fixes this.

1 Like

You can install them from homebrew as well

brew tap azure/functions
brew install azure-functions-core-tools

I'm thinking of adding it as a dependency, but there are other ways to install the Core Tools, like from NPM, so I didn't wanna mess the version the user is using or cause conflicts

BTW: I think Brew has ways to detect existing installs of necessary binaries and only add the dependency when required (or requested).

Glad it worked! For the TERM message, I have not seen it while testing before. I do provide that to func host start to retain the output format and colors. Can you please provide with more info about the environment? Are you running it from the macOS Terminal app or another terminal? I've tried in Terminal & VSCode Terminal but didn't get the message. Also I'm going to test locally without setting TERM.

For the Azure Functions Core Tools installation requirement, I'm going to check the homebrew dependencies config :smile: It would be nice to save a step from the prerequisites!

For the .NET Core SDK, I've added the Extensions Bundle to the function projects created by swiftfunc so it shouldn't be required anymore. I'll update the docs. The root permissions issue, has an open issue on Github, did you get it while installating from Homebrew?

Regular Terminal.app, on 10.15, but w/ bash:

helge@Zini18 ~ $ env
TERM_PROGRAM=Apple_Terminal
SHELL=/bin/bash
TERM=xterm-256color
TERM_PROGRAM_VERSION=433

The SDK (unfortunately) isn't shipped as a regular formula but as a cask, which presumably just bundles the SDK installer. And yes, it prompted me for credentials.

1 Like

@Helge_Hess1 I tried to repro the message you got about TERM, but I didn't have it in any of the shells. Interestingly, TERM is set to the same value you have. I'm testing the effect of removing it from code and it doesn't seem to affect it so far. Btw, I'm curious, have you got the same message again after a restart or in a new terminal window/session? I'm glad it worked for you!

UPDATE: I was able to repro the message you got with the latest V2 Core Tools. I've updated the Swift Functions CLI now with the fix :smiley: Please update to the latest version. Also I filed a Github issue with the solution on the repo for reference!

1 Like

I will need to try it out, since I wrote about the managed version of Apache OpenWhisk project with Swift in details in the Serverless Swift book by Apress https://www.apress.com/us/book/9781484258354 . I will let you know about porting my examples to Azure as well!

1 Like

In terminal run the following to create a new project:

swiftfunc init myFunctionsProj

If you’re used to using Functions Core Tools, Swift Function Tools are pretty similar. The init command we ran above is similar to that of the Core Tools, but it's going to create a Swift Functions Project! You're going to get the follow folder structure:

The project is basically a SwiftPM project with a couple of extra files for the purpose of Azure Functions framework.

The functions folder is going to be the home of your Functions!

1 Like

Exactly! :smile:

The amount of dependencies feels quite weird, e.g. why do I need to package Vapor just for a server less runtime? The Lambda runtime doesn’t need any of that.

1 Like

There are 4 dependencies. They seem reasonable to me given an azure function can serve http traffic.

dependencies: [
    // Dependencies declare other packages that this package depends on.
    .package(url: "https://github.com/vapor/vapor.git", from: "4.8.0"),
    .package(url: "https://github.com/Flight-School/AnyCodable",   from: "0.2.3"),
    .package(url: "https://github.com/grpc/grpc-swift", .exact("1.0.0-alpha.12")),
    .package(url: "https://github.com/JohnSundell/Files", from: "4.1.1"),
    .package(url: "https://github.com/stencilproject/Stencil.git", from: "0.13.1"),
],

I count 5? Those are just the root dependencies. To do HTTP traffic there is SwiftNIO (as used by the Lambda Runtime).
It is reasonable for a framework build on top, but not for a runtime component. I for sure don't want any Vapor :slight_smile:

Would be cool to see something comparable to the Lambda runtime (low level, to build things on top). I might adjust the cross compilers / swift-lambda to support Azure, if this happens.

4 Likes

@Helge_Hess1 You're right, thank you for the feedback. Let me explain the dependencies.
First, Azure Functions provide 2 ways to support languages/runtimes. gRPC & HTTP (initially only gRPC but later HTTP Custom Handlers were introduced). This framework currently supports both. There are differences in writing an Azure Function in each approach.
Second, I used Vapor just to get things wired as this framework was one of the very first to support Azure Functions Custom Handlers when they were in preview.
I'm working to switch to SwiftNIO instead of Vapor for the HTTP worker (SwiftNIO is already used by grpc-swift).
This framework along with its CLI, supports all major Azure Functions deployment methods possible, in container or zip package deployment. In addition to testing locally on Linux or macOS.
I will provide updates here on my progress on SwiftNIO switch :smiley:

Hi @_saleh, that sounds promising! I think gRPC is just fine as it is also an unopinionated infrastructure component, not a higher level framework.

Why do you need the Files and Stencil packages, both seem very off for such a low level package? (i.e. a driver for a higher level frameworks)

BTW: The extra swift-lambda does is producing a target executable right on the Mac (even M1) using the SPMDestinations cross compilers. I'd think that might be interesting for Azure as well ;-)

Even though this is not exactly in your interest, I also think that it would be nice for the Swift community to have a builder which can deploy to both AWS and Azure (and others like Scaleway, etc).

2 Likes