AWS Bites Podcast

128. Writing a book about Rust & Lambda

Published 2024-07-25 - Listen on your favourite podcast player

In this episode, we discuss Luciano's new book project on using Rust to write AWS Lambda functions. We start with a recap on why Rust is a good fit for Lambda, including performance, efficiency, safety, and low cold start times. Luciano provides details on the book's progress so far, the intended audience, and the current published chapters covering Lambda internals, getting started with Rust Lambda, and building a URL shortener app with DynamoDB. We also explore the differences between traditional publishing and self-publishing, and why Luciano chose the self-publishing route for this book. Luciano shares insights into the writing process with AsciiDoc, code samples, SVG image generation, and using Gumroad for distribution. He invites feedback from listeners who have experience with Rust and Lambda.

AWS Bites is brought to you by fourTheorem. If you are looking for a partner to architect, develop and modernise on AWS, give fourTheorem a call. We have also been working with some of our customers to rewrite some of their most used Lambda functions in Rust, greatly reducing cost and improving performance. If all of this sounds interesting, check us out at fourtheorem.com!

In this episode, we mentioned the following resource:

Let's talk!

Do you agree with our opinions? Do you have interesting AWS questions you'd like us to chat about? Leave a comment on YouTube or connect with us on Twitter: @eoins, @loige.

Help us to make this transcription better! If you find an error, please submit a PR with your corrections.

Luciano: Hello and welcome to another episode of AWS Bites podcast. My name is Luciano and I'm joined by Eoin to discuss a new side project. I'm currently writing a book about Rust and Lambda. So today I want to share with you some of the details about this project. Why do I think that using the Rust programming language to write Lambda functions is a great idea? What you can expect from this book and a little bit about the publishing process.

I think that Rust is innovating many areas of the software engineering world and my bet is that in the coming years we will see it innovating and improving the world of AWS Lambda as well. So I hope that this is going to be an interesting episode and let's get into it. AWS Bites is brought to you by fourTheorem. If you are looking for a partner to architect, develop and modernize on AWS, give fourTheorem a call. By the way, we have also been working with some of our customers, rewriting some of their most used Lambda functions in Rust, which is something that greatly reduces cost and improves performance. So if all of this sounds interesting, check us out on fourTheorem.com.

Eoin: Okay, I remember episode 64 where we talked about writing Lambda functions in Rust. So that's not the goal today, I think. We want to talk a little bit more about the book, but at the same time, maybe it's worth a quick recap because that was about a year and a half ago. I think a lot happens in a year and a half in the Rust and in the Lambda ecosystems. So do you want to remind us why it might be a good fit for Lambda functions?

Luciano: Yes, I'll try to do a quick recap about Rust first, and then we'll talk about Rust in the context of Lambda. Maybe people are not familiar with Rust. So Rust is a relatively new programming language, was born to compete with C and C++, mostly in terms of performance, but the idea was to try to provide a better experience in terms of a language that is memory safe by default. And that kind of memory safety is built into the language and the compiler.

It does have a very good and modern toolchain, and the language itself is very modern as well, and it takes inspiration by many other languages. And because it also provides a few different high-level abstractions, these days Rust has become more of a general-purpose programming language. So it's not being considered as a system programming language anymore because you can write from firmware and an operative system and video games, but also you can write more high-level applications such as web backends and even web frontends using WebAssembly.

So it's kind of a language that has become general purpose and you can use it for a variety of projects. And one of the main things is that software written Rust can be very memory efficient and very performant and also based on some research that has been done, if we look at the consumption in terms of electricity consumption and CO2 emissions, Rust can also be environmentally friendly, and it's considered to be one of the most environmentally friendly languages out there.

Now, in the context of Lambda, why Rust is an interesting choice? We said already that it can be very memory efficient and fast, so that means that you can lower down the cost, the execution cost of Lambda function if you write them in Rust. And just to remind you what's the execution cost, you basically have to take a unit cost based on the amount of memory that you allocate for your Lambda function and multiply that by the number of milliseconds that your execution is lasting.

So with Rust, you generally get Lambda functions that don't require a lot of memory, depending of course on the problem that you're solving, but if you compare an equivalent implementation between, for instance, JavaScript or Python and Rust, generally the Rust implementation doesn't require nearly as much memory. So you can save a lot in terms of allocated memory, which reduces one unit of cost. Then, generally speaking, Rust can execute very fast, especially when you have CPU-bound computation.

So in that case, you are also reducing the number of milliseconds, most likely, that your execution is going to last. So basically, you are optimizing on both dimensions for the Lambda execution cost, which generally means that if you have a Lambda that you are executing thousands or even millions of times per day, if you rewrite that one in Rust, you are going to probably save a lot of money. Now, this is of course not the only reason why you should consider Rust.

There are other few reasons that I think are interesting. Another one is that if you have, let's say, user-facing Lambdas or Lambdas where you expect to have a very low latency in the response, you might have occasional cold starts, and that might be a problem if there is a user waiting for that cold start. Imagine you are writing like an API and you want this API to be consistently very responsive and very low latency.

With Rust, you don't avoid the cold start, but the cold starts are so low, I've seen in the order of 20 to 40 milliseconds, that they are becoming basically negligible. So that's another good use case for considering Rust. And then there are another few interesting reasons. One is that, as I mentioned, the language is very modern and imporals some constructs in the type systems that will help you to prevent a certain classes of bugs.

So, for instance, there is the result type, which basically helps you to manage exceptions, or the option type, which avoids the classic null pointer exception that you have in other languages. So, generally speaking, the programming language itself helps you to prevent a large class of bugs and write code that can be generally more correct. So if you have business-critical applications where you want to have, I guess, extra peace of mind that the code that you are writing is probably not going to be bug-free, but as close to bug-free as possible, I think Rust can help as well in that direction. And we also mentioned reducing CO2 emissions. Lambda is already a great platform for that. But if you combine that with Rust, I think you get an even better, I guess, stance on being environmentally friendly when it comes to compute in the cloud. Now, again, I want to remind you that we have been speaking a lot in that previous episode about the whole experience, how do you get started, the tooling, the pros and cons of using Rust. So if you're curious about, like, actually, how do you get started and how do you write your first Lambda in Rust, I would recommend people to check out that previous episode.

Eoin: All right, let's talk about your book then. So what is the title and who's it for? What's your intended audience? Or have you thought that much about that so far? Because a lot of people don't.

Luciano: Yeah, I would probably say a little bit. It's probably something subject to change, but we'll get to the details of that. The title of the book is called Crafting Lambda Functions in Rust. There is a website that provides all kinds of information, and the website is reachable at rust-lambda.com. The link will be in the show notes as always. So what is the expected audience? And this is a bit of a guess at this stage of the book, but we are imagining the book to be something that is designed to be accessible to readers that have a very basic knowledge of Rust and AWS, so not meant to be consumed only by experts, but also by people that are a little bit entry level on both Rust and AWS.

We want to try to provide a gentle introduction to the serverless ecosystem in AWS, which also means that you don't need to be proficient with serverless in general, Lambda, or DynamoDB, and all the other classic serverless services in AWS. The idea is that, of course, you need to have your own AWS account and have some very basic knowledge about what you can do with AWS. So you need to be able to access the dashboard, maybe know a little bit about IAM, but you are not expected to be an expert in all things AWS.

And in fact, throughout the book, we try to introduce all the necessary concepts, so not just explain what Lambda is, how does it work internally and how do you start using it, but then as soon as we start to use Lambda with API Gateway and DynamoDB and other services like EventBridge, maybe we introduce those services, giving, I guess, the fundamental knowledge that you need to have to understand how to build something practical with those services.

And we also touch a little bit on infrastructure as code and we use AWS SAM for that. As I mentioned, you don't need to be an expert in Rust either, but of course, we cannot explain everything about Rust because that would make the book probably thousands of pages. So just to be practical and pragmatic, what we suggest is that people should understand a little bit of the syntax. And if that's something that you don't know yet, probably the best thing you can do is to look at the official Rust book, which is available for free.

And we will have the link at the show notes as a starting point just to get familiar with the syntax. So just to summarize, this book is for you if you are a cloud developer with a passion for serverless, you have a very basic understanding of the Rust programming language, at least from a syntax understanding perspective, you have a basic knowledge of AWS, and you basically are trying to figure out a new way to build greener, more efficient and cost-effective serverless solutions. By the way, I mentioned the we a few times, so it's definitely worth stating that it's not my own solo side-project. I've actually been working with a co-author for this, and the co-author is James Eastham. And James is an amazing author with lots of experience with serverless and event-driven systems. He, by the way, used to work for AWS and recently moved to Datadog, and he has an amazing YouTube channel that talks a lot about serverless, AWS, event-driven architecture. So if all these topics interest you, you should check it out, and we will have the link in the show notes as well.

Eoin: So what's the current status of the book? Is it a work in progress? How far have you progressed so far?

Luciano: Yeah, the book is heavily work in progress at this stage. We started, I think, about two months ago now, so it's still relatively, it's a good progress project. And another thing worth mentioning is that it is self-published. Probably we'll get more into that later. And the current version, what we have so far is four chapters, which is about 110 pages or something like that, around 100 pages, more or less.

And we have the book already available online. So you can buy it today as an early preview, and you get about 50% of discount on the expected final price. And that means that you can download what we have written so far, and then you will receive all the future updates of the book for free. And since it's an e-book, you get a few different formats. So there is a PDF, which also comes in dark mode, if you prefer that.

There is an e-book format, and there is even an HTML format. So you can read it in whichever format you prefer. Right now we have four chapters, and those chapters cover, In the first chapter, we do an introduction to what Lambda is, what is Rust, why the two together make sense, which is more or less what we described at the beginning of this episode, plus a detailed introduction about serverless AWS Lambda, and how AWS Lambda works under the hood, because we believe that it's important for you to understand a few important details about Lambda, like the internals of Lambda, like what is a runtime, how different environments are created and reused and destroyed.

So we try to explain all of that just to give you a good context to understand the computation model. On chapter two, we start to build a first Lambda function. It's kind of an L award, and it's just to get familiar with the toolchain, including Cargo Lambda, which is a CLI tool that you can use to do scaffolding of new Lambdas, local testing, building the Lambda for different architectures, and even publishing the Lambda to AWS.

Then in chapter three, we start to build a more realistic application, a URL shortener, and we use this opportunity to start to introduce infrastructure as code and explain what SAM is and how to use SAM together with Cargo Lambda. And then in chapter four, which is currently the last chapter we have, we continue developing that application, and we bring it to a state where it's more or less working because we start to persist the data in DynamoDB, so you can actually create a short URL and use it across different implications of Lambdas.

And in the process, of course, we need to learn what DynamoDB is, what are the trade-offs of DynamoDB, how to use the SDK for Rust to interact with DynamoDB, and we also learn how to make arbitrary HTTP requests from Lambda because we want to effectively crawl the URL for which we are creating the short URL to establish a title and a description from the page metadata. So this is just a nice example to see that in a Lambda, you generally will need to do some kind of HTTP request. So how do you do that? What are the different pieces of configuration and libraries that you can use to do all of that? So I think this is what we have so far, and by the end of chapter four, you have a working implementation of a URL shortener. It's not perfect because it's still very bare bone and there are lots of corners that we've cut to get there, but at least it's something working that you can deploy in your own account and use it.

Eoin: That sounds great. You've made a lot of progress in two months, I think, to have those four chapters out there, and people can have a look already. That's really one of the benefits of self-publishing, I guess. But what about the whole scope? Do you have an idea of what the whole shape is going to be by the time you've finished? What else do you expect to cover?

Luciano: Yeah, I think ideally what we want to cover throughout the entire book is not just an introduction to serverless and Rust in the context of AWS Lambda, but more making sure we touch on all the things that you need to be aware if you want to do something that we can consider production-ready. So that means that now that we have kind of a skeleton of an application, which is definitely not production-ready at this stage, what is missing to make that production-ready?

And what we see that we should be covering is things like best practices in terms of structuring the code. For instance, if you have multiple Lambda functions in the same project, which is very common, how do you organize those in the context of Rust? And then if you have shared libraries, which is also very common, that you need to reuse across these Lambdas, what is the best way to do that? And similarly, how do you make your code testable, especially in an environment like Lambda, where you generally interact with a lot of external systems, like for instance, even DynamoDB, we can imagine it's an external system.

How can you write, for instance, unit tests to cover, basically, to make sure that your code is working correctly and run this test and have the kind of extra confidence that you are doing the right thing? And also touch about integration tests and end-to-end tests as well. Then right now we are only covering HTTP events. So you are building an API. So your URL shortener is just effectively an API. You can use it as an API and that's it.

But what if you want to use other event sources, for instance, DynamoDB Streams or EventBridge, or maybe even custom events, maybe you are building a step function and you have a step, which is a Lambda written in Rust. So we want to cover some examples about these different kinds of events that you can get and different kinds of integrations with different AWS services. And then there is the topic of observability.

So we need to cover how to do good logging, tracing, integrated with CloudWatch, maybe explore open telemetry as well, which seems to be a topic that is more and more discussed in the context of Lambda. And it's definitely well supported in general in the Rust ecosystem. So trying to see how you can use it together with Lambda could be interesting. And then finally, configuration management and handling secrets.

There are some other topics that we are considering maybe as an appendix or maybe as advanced chapters. We'll probably see what happens as we get there. But there is an interesting middleware system that is built in in the Rust runtime. So it could be interesting to show that, like the capabilities that you have, to show how you can use existing middlewares, but even creating your own middleware. And you can also write Lambda extensions in Rust.

And this is very interesting because you can use those extensions even in Lambda functions written in other languages, like Python or Node.js. And this is something that, for instance, if you are somebody that is creating something like Datadog or other system where you want to collect telemetry or maybe send data as part of your Lambda execution life cycle, you could create a Lambda extension written in Rust, which will be very efficient and have a minimal impact on whoever is installing that extension.

So that's something that could be interesting to explore as well. And then finally, there are other topics such as if you want to create like a CI-CD pipeline, maybe using GitHub action, providing some example of how you can tie everything together. And finally, maybe considering alternatives to SAM, like using CDK or Terraform because everyone has its own preference. Of course, we have to pick one and SAM seems to be the easiest to explain. But if you are already familiar with CDK and Terraform, it might be worth explaining or at least showing some examples of how you can achieve the same things by using your favorite infrastructure as code tool. So it's important to mention that this schedule is not final. We are trying to get as much feedback as possible and use that feedback to understand, okay, what should we be covering next? Maybe we should focus more on one topic rather than others. Yeah, look, that sounds fair enough.

Eoin: A long time ago, well, maybe not that long ago, but a while back, I wrote a book with Peter Elger and it was kind of published with Manning. So there was also an early access program, but I guess it wasn't self-published. So we had editorial support along the way. You've also written a book, Node.js Design Patterns with Packt. So what do you think the trade-offs are then between self-publishing versus going with a publisher? And why in this instance, with your experience, did you go for this model?

Luciano: Yeah, you're definitely saying that there are trade-offs. I totally agree with that. There's not like one model is necessarily better than the other. I think you need to evaluate the pros and cons and decide which one is the best. So I definitely don't regret going with a publisher for Node.js Design Patterns, but I was also curious to see what it would look like to try to do a self-published book. And I think in general, when you go with a publisher, the publisher will take care of many aspects of the process.

So you can focus most of your time on basically the content itself. So writing down the content and making sure the content is up to the standards that you want to provide. So in that case, when you have a publisher, the publisher will help you a lot, first of all, to define the structure of the book, more or less what is in terms of like broad strokes, that the topic that should be covered and how to distill down the topic based on a target audience.

So the publisher will also help you a lot to make sure that you understand what is your target audience and to tune that content to that target audience. Then one of the things that the publisher does best is establishing a timeline and making sure that you stick to that timeline. They also help you to find reviewers and editors. They will help you with graphics, layouts, publishing, all that kind of stuff.

And of course, the big element is also marketing and branding because of course, with a publisher, there is a little bit of extra trust that you get because if people know Manning or Packt, they will trust that brand probably more than they will trust an author that they've never seen before. So as I said, they also make sure that you don't get stuck. So sometimes when you write a book, you realize that maybe there is something you don't like and you want to take a very big change.

I think the publisher will make sure that you evaluate those kinds of changes really, really well and you don't end up spinning up in circles and not really focusing on delivering something because maybe you keep changing ideas. So that's also very good for focus and making sure you actually deliver a complete project rather than, I don't know, maybe trying a few different things and then giving up. And I think all these things are great if you are a first time book author because you will need to understand that kind of process.

You'll need to have the diligence. You'll need to have somebody to support you and also push you when you need to be pushed. But on the other end, there are some other cons to having a publisher. One that I think is very important is that you don't really have a lot of flexibility. So you have to stick to that particular process that they have in place. And sometimes that process can be a little bit annoying.

For instance, with Packt, it means that you need to use Microsoft Word and all the templates that they provide without the styling that they have already established, which of course is good for them because they want to be consistent with their branding and they want to be sure the final product is going to look as they expect. But if you don't like the kind of tooling and the kind of way of writing, it can become very annoying, especially when you have to write hundreds of pages.

So that's one thing that is worth considering. Then there is also the financial perspective. So the publisher takes the bigger share of the revenue. And even if you are an established author, maybe you can negotiate a little bit of a better deal, but it's not going to change the equation significantly. So that's something to keep into account. I still think that writing a book is not something that you do for getting rich.

Realistically, you are not going to pay, you're not going to get paid as much as you would get paid if you were spending the same amount of time just doing your software engineering job. So the value of writing a book is not, I guess, the financial return that you might get from it. But if you do self-publish, I think that equation changed significantly where at least I think you can get your time paid off well enough if the book is successful.

So that's something else worth considering. Like if you're looking for a slightly better return, self-publishing can give you all of that. But that also means that you have to do all the extra work that the publisher is doing for you. So the process itself is more complicated because you need to spend all that extra time to do all the things that the publisher will be doing for you. In terms of our process, I'm really happy that we are not using Word for this particular project, but we figured out a different tool chain.

In particular, we are using AsciiDoc, which if people are not familiar with it, is a language that is somewhat similar to Markdown, but much more powerful because it was built effectively to write books. So there are so many more features that you don't have in Markdown. And we found a very good starter template provided by Liran Tal. We will have the link in the show notes. If anyone is curious to see what that looks like, maybe I think you need to write a book as well. I think that could be something that saves you a lot of time because it's already a structure for you to take care of most of the things, including for instance, the publishing in different formats and supporting dark mode for PDFs. Can I just ask about the build process Luciano?

Eoin: Actually, I remember that with Manning, they did, while they had a word option for doing editing, they also had an AsciiDoc option where they give you templates and it was easy enough then to, you know, build, create a source code repository, build your book with a GitHub action or whatever that worked pretty well. But one of the things I remember that's really quite time consuming when you're doing this kind of process is taking, merging your code samples and your book content and images as well.

So we were doing an AWS book, so we had code samples, we had then the source code for the book text itself, and then we had screenshots, which were manually screen grabbing, you know, high DPI, copying in, having to like manipulate them in various different ways to make them look right. And that's actually quite a slow process. I remember hearing Dave Thomas from the Pragmatic Programmer and he has his own publishing company. And I remember him saying that they set up a build process that would actually build and test the code in the book as you're building the book. So I'm just wondering if you've got any neat tricks or if you're also just taking a manual approach when it comes to incorporating those snippets.

Luciano: Yeah, I know that in AsciiDoc, you can include snippets from source code directly. So there is a way to do that. We are not leveraging that yet because since we are building like a real application and we show like a few steps to get to something working, then if you go on the book repo where you see all the code, the code is more or less like the final state of that particular chapter. So it is a little bit tricky.

Like we cannot just include the final state. We need to explain all the different steps. So it is a little bit tricky to reconcile the actual working code with a step-by-step explanation of how do you get to write that code. So right now we are still doing mostly manual things in that sense. And yeah, also the other thing is that you might want to highlight, for instance, the differences between step one and step two.

And again, that's not something that you implicitly have in a working code base. So you need to apply all the formatting in that sense. And thankfully, AsciiDoc makes that relatively easy, but there is still a significant amount of manual work to do all of that. And it can be painful if at some point you decide to do a big refactoring. That means that you need to go back in all the steps and figure out how do I apply.

Do it all again. Exactly. In terms of images, so far we've been using only SVGs because we don't really have screenshots. And we created a little tool that allows us to convert an SVG to the equivalent dark mode. So basically what it does, inverts the colors, and then you can specify in the SVG markup when you don't want the color to be inverted, for instance, I don't know. If it's the orange of the lambda icon, we probably don't want that to be inverted in the dark mode. So we have a way to do that. But if we regenerate the base image, it's just a command line that we need to run to regenerate the dark mode version. So that helps a little bit to speed things up.

Eoin: Nice, so where is the shop front and how are you processing the money side of things for the book?

Luciano: Yeah, that's something that we had to research a little bit. We ended up choosing Gumroad, which I don't know if it's the best in terms of pricing because I think they take a flat 10% of revenue. And I know that there are other shops where you can get a better deal. 10% is not necessarily a lot, depending on the price that you have.

Eoin: Compared to Apple!

Luciano: Exactly, but I know that there is, for instance, Lemon Squeezey, it gives you a better deal in that sense. But what we were looking for is to have something that is simple enough to use, and at the same time that could automatically split the revenue between the authors. And apparently Gumroad is the only one we found where this feature exists. And this is amazing because from a tax perspective, everyone receives their own share of the money, everyone is liable to do their own tax report if we don't have to create like an intermediate company or do, I don't know, invoicing or moving money between the authors.

So all of that management, which honestly it's something I was a little bit scared about, is taken care by Gumroad. So I'm really happy about that aspect. So the other thing is that in Gumroad it's very easy to generate discounts if you want, for instance, maybe you are attending a conference and you want to create a discount code just for that day to incentivize people to buy the book after they hear your talk.

Gumroad makes all of that extremely easy. So that's another thing that I wasn't missing from the relationship with the publisher where you can get discount codes, but you need to be very careful to ask way in advance. And sometimes it just doesn't work out and you lose opportunities. So yeah, generally speaking right now, I'm very happy with the whole self-published experience. I think that the only tricky thing is to try to stick with some kind of timeline or at least to have a good cadence even if you don't really have a strict deadline, but at least make sure that you are progressing steadily on the book. And I think being two authors helps a lot because we can kind of push each other and try to keep each other accountable. And that makes sure that we keep progressing with some kind of a reliable pace. So I don't know if you have other questions, otherwise this is, I think, everything I wanted to share so far.

Eoin: I'm curious, maybe in the future, when you're closer to the finish, we can talk about it and we can go through some of the contents in a bit more detail and maybe have James on as well. But that was really interesting. All I can say is best of luck with it. Thank you. Yeah, I'm going to get reading.

Luciano: Nice, yeah. We'll definitely have all the links in the show notes again. And if you end up getting the book, I'd be really curious to get the feedback, because again, we are trying to use as much early feedback as possible to try to drive basically the evolution of the content itself. So also I'm curious in general, if people have considered writing Lambdas and Rust and why, if they actually tried it, what the experience was like for them. So if that's something that you have done or even just consider, leave us a comment because I'd be really curious to read about that experience. So thanks again for being with us today for another episode. And we look forward to seeing you in the next one. Bye.