Elixir on AWS Lambda is coming soon

deployment
aws

#1

AWS re:Invent is on at the moment with some interesting announcements. One new feature in particular is the Lambda Runtime API for AWS Lamda. This is how they’ll be supporting new languages on AWS going forward (they just added ruby support through this API).

They’re already working with Alert Logic on building a Elixir and Erlang runtimes.

Looking forward to trying this out. I wonder how well the BEAM would work given it has relatively slow startup time. Still though, no need for a server, spawn up a process, do some work and you’re done, could be interesting.


Elixir on AWS Lambda
#2

Wow, that’s pretty big news for people into serverless. I’m glad to have Elixir/Erlang supported there even though I personally probably won’t use it. It’ll definitely be interesting to see how they develop it.


#3

It is a little concerning that AlertLogic consistently misspells Elixer in their announcement.


#4

You should hear the people from my country almost always pronouncing and writing it as “Elexir”… :107:


#5

Stumbled across this today


#6

I got the example working (https://github.com/aws-samples/aws-lambda-elixir-runtime). It was a bit of a hassle since I work on a Mac and then you cannot compile and build a release locally as it is a different platform than what Lambda runs on. So, I had to build the release within a Docker container, extract the build artifact and upload that to Lambda.

Just noticed https://github.com/alertlogic/erllambda_elixir_example does the same.


#7

How were response times?

Did you measure cold start, hot start etc?


#8

I’ll try and get back to you on that. Maybe I’ll do a writeup somewhere.


#9

I had to build the release within a Docker container

Nice! I think that’s pretty common. Most recently I had to do this with python and Pillow. I also watched Kelsey Hightower extract the binary from a container running Fortran and ran it on lambda, which was pretty cool. I’m glad to see elixir get recognized here.


#10

Guys, what do you think could be a useful use-case for elixir in aws lambda?

For sure a great visibility for the language and the community … but I honestly don’t see elixir apps to be a good fit for aws-lambda as disposable functions. I see erlang/elixir strong on other things like macros (elixir), concurrency model etc… to run an app that needs to be fault-tolerant not to be run for 30seconds and thrown away…


#11

The same use case for any other language in lambda. Honestly, I haven’t found a reason to use anything other than python because boto3 is awesome. I have mainly used it for one off tasks that I don’t feel like building into the main app. Recently I’ve used it to process SQS using amazon polly. The elixir app is just running a genserver listening to the queue for completed items. How that text gets synthesized the elixir code doesn’t need to know or care about. So decoupling is a good use case. Especially when your language of choice is lacking integrations.

Kelsey Hightower (Mr. Kubernetes) gave a talk called the Path to Serverless. It’s a really good talk and I think it covers the basics of why serverless is important. Despite what I feel like is an over analyzation of the technology, the fact is you don’t need to maintain a server to run some code. It’s that simple. Serverless has been around since you could upload php files to a server and it just runs. We have serverless file hosting (s3), serverless database hosting (RDS), serverless queues (SQS), etc. Lambda is just serverless compute. Some people take it to the extreme and run entire web applications, and that’s fine but I think it depends on the scale. For example, we run a lambda that gets triggered when a thumbnail object is not in s3. This lambda generates the thumbnail on the fly, saves it to s3 and returns the image. These requests typically occur in large burst, lambda makes this trivial to handle the load. I have yet to pay a penny for the compute time.

Another important aspect with lambda is it’s triggers. This allows your cloud infrastructure to respond to events. Not everything is a http request. The use cases will evolve as the tech matures. Elixir on lambda would be good for api endpoints and glue functions. It’s also very cheap. Technologies like lambda **cough** firebase **cough** give react/vue devs and easy to implement backends. There are a lot of front end apps that are most static but contain small forms such as newsletter signup. Having elixir be a documented option helps language adoption. Official recognition is huge. Getting elixir in early gives developers the opportunity to solve real problems with their preferred language and add more use cases.

to run an app that needs to be fault-tolerant not to be run for 30seconds and thrown away

Lambda doesn’t just throw itself away when the function is done. The same event can trigger the same running lambda many times. Lambda is also as fault-tolerant as it gets. The problems lambda solves is definitely inline with the problems elixir solves but they’re not mutually exclusive. I think that’s very good for elixir. Technology like lambda will only continue to evolve. Today we have options, you could put an ALB with path based routing in front of long running stateful elixir code and short lived stateless lambda code (elixir or not). Take advantage of all the tools.

It’s not for everything or everyone, but dismissing something because of perceived value is not always wise. One could argue they don’t see the point of running elixir on kubernetes. It’s not about replacement, it’s about adding a tool and utilizing the right tool for the problem.


#12

Thanks a lot for your reply and to sharing the video, I’m going to watching this in evening!

I’m not saying aws lambda is not useful (actually I think the opposite), it’s just that I’m used to see aws lambda as triggered short-time tasks. In my team we use it a lot for text classification using python machine learning libs. A text document is saved on s3 and this triggers an event which is received and processed by our classification lambda function, and this works really well.

I would maybe use elixir in aws lambda to process a huge csv with millions of rows, since I like lazy functional approach to handle this kind of files and I love the Elixir’s Streams, so I can see me using Elixir, on aws lambda, for this kind of situation. Timeout was an issue but I’ve just seen they increased it upto 15mins which is great)
But my point is another one… is Elixir the best for this kind of job? I’ve just ran the hello_world example and it needs more than 100mb to start the VM and print the hello world string. While I don’t really mind about few hundred Mbytes of overhead when I’m running a a distributed application that needs to stay up for days/months/years.


#13

I hear you. For all my use cased I haven’t found reason not to use python. If I were to use elixir with lambda today, I would probably utilize it the same way people have been using it for node/express. If I were to pick between node/express and elixir/phoenix I’d choose the latter. Getting an app up quickly and only worrying about the product and not the infrastructure is always nice. I’d consider using it for glue functions, but of course boto3 is really nice and most of the time glue functions interact with other aws resources. I do not see the point of lambda when building stateful elixir code. Fargate is another interesting serverless option and now that they’ve reduced the pricing it’s a nice compromise for an elixir app. I think Fargate and Lambda will eventually be capable of the same thing. I’m pretty confident the underlying tech is same especially since they open sourced firecracker. I feel all languages should be able to fit in an elastic environment. Especially with the rise of docker and kubernetes

This is one of my favorite talks, I think elixir and it’s future looks bright for elastic (containerized) environments.


#14

Just finished watching this video! Great video, especially to start thinking a clean solution to hot code swap in a kubernetes cluster. I think the solution he mentioned at the end, to do a hot code swap on a live container, should be easier and maybe cleaner. Daniel said that gigalixir does hot code swap on live containers mounting volumes… but still I don’t understand what he meant, since it’s not possible to mount volumes on a running container.
What is possible to do though, is to have an NFS volume mounted into each container/pod so they can access to the new release and update accordingly. There could be another pod in the cluster which act as update-agent, sending a message to the elixir pods asking them to update the code.
There is still a problem about the image. We obviously build the new image, in the case one of the containers restarts. But we need a way to tell kubernetes that there is a new image version without terminating and spawning new containers…

UPDATE: I’ve just found this https://hexdocs.pm/distillery/guides/working_with_docker.html


#15

But we need a way to tell kubernetes that there is a new image version without terminating and spawning new containers

I’m sure there’s a few different ways, but I think this goes against containers ideology. Because container are intended to be ephemeral, this can feel like a conflict with the idea of stateful elixir processes. But, I also believe the distributed nature of elixir/erlang makes this problem easier to solve than other languages. Hence the video above. We also can’t ignore other technologies that help apps work distributed. Redis/RabbitMQ are two that come to mind that are simple to get up and running. I like the global registry concept and horde is eventually going to be api compliant with elixir registry. I think using exrm on vm’s and skipping docker is probably ideal for hot code swapping. BUT it’s the end result that matters. And if we can “hot swap” the container using the tools provided in the elixir ecosystem and maintain our process state, that accomplishes the same thing as hot code swapping. Daniel proved in his video that this is possible even with realtime multiplayer games. It’s an area I’m interested in, I don’t have a ton of hands on with docker and elixir yet, but internally we do run an elixir app across 7 nodes. We don’t deploy “code” we just update the stack to reflect new images and use docker swarm. Honestly couldn’t be easier and the distillery docs were extremely helpful! Using a container orchestrater makes hot code swapping practically impossible. I’m looking forward to advancements in this space for the elixir ecosystem.

BTW, I just noticed this is your blog www.poeticoding.com and I have to say I really enjoy the articles!

EDIT: libcluster can be used for auto discovery.


#16

Thanks a lot! :smiley:

I agree with you that the containers are not ideal for stateful processes, especially when the only way to update the container image is via a blue/green update. I don’t really like the idea of updating the version injecting the code into a running container… but I find it simpler and less prone of issues than killing the containers copying the state. The distributed way to do containers update is fascinating but I see a lot of things that can go wrong, like “grace” termination period not long enough to copy all the state, or if we have a high number of processes holding states in the memory etc… Would be nice to spend some time experimenting a little bit!

I’ve also tried libcluster in the past for a small phoenix app in a k8s cluster and works really well! I was just using it to discover the phoenix nodes and connect them together.


#17

You can write move complex lamda with aws step functions. Even lamda functions can fire child lamda functions. But you must remember that you will be charged more for lamda than time on some ec2 machine. So it does not make sense to run log running processes on lamda IMO.
For me lamdas is event driven design that glue some long running services (your services or AWS services)

https://cloudevents.io/

Cloud computing requires to not only treat containers but also servers like “Cattle”
What would happen if someone kill your server and you lost all your state?
http://cloudscaling.com/blog/cloud-computing/the-history-of-pets-vs-cattle/ :slight_smile:

12 factor apps

VI. Processes
Execute the app as one or more stateless processes
https://12factor.net/processes

PS
Interesting article about cost


#18

I agree with you, but this is more a generic problem, we could have also with normal servers. If the process crashes (or the server fails/reboots) for any reason, the state is lost. The only way to avoid this is replication or at least persistency of the state.


#19

I heard on one podcast how online bank was designed:

  1. The client request transaction
  2. The transaction request is saved in database and the client gets success message
  3. The transaction is scheduled to be run on machines (the machines are created if needed). If for some reason something fails the state is cleaned and runs from the begging.

#20

A lot of larger collections of microservices use persistent queues in this way: most commonly Kafka in larger enterprises, RabbitMQ (or maybe VerneMQ) in the Erlang world.