Summarized using AI

Jets: The Ruby Serverless Framework

Tung Nguyen • May 17, 2019 • Sofia, Bulgaria • Talk

Jets: The Ruby Serverless Framework

In his presentation at Balkan Ruby 2019, Tung Nguyen introduces "Jets: The Ruby Serverless Framework," which he developed to enable native use of Ruby in serverless applications. He shares insights on AWS's Lambda and how Jets provides a simplified way to create serverless applications using Ruby.

Key Points Discussed:

  • Introduction to Serverless Frameworks:

    • The concept of serverless computing and the significance of AWS Lambda in the cloud ecosystem.
    • AWS's announcement of Ruby support in Lambda highlighted the need for Ruby developers to have a robust serverless framework.
  • Benefits of AWS Lambda:

    • Avoidance of server management, allowing developers to focus primarily on writing code.
    • Automatic scaling of functions without manual configuration.
    • Economic model of pay-per-request offering significant advantages, especially for startups and personal projects.
  • Serverless Architecture Components:

    • Description of foundational AWS services like Lambda, API Gateway as a routing service, and CloudWatch used for scheduling.
    • Explanation of DynamoDB and RDS Aurora for database management within serverless applications.
  • Common Challenges and Considerations:

    • Addressing limitations such as RAM and code size constraints in AWS Lambda.
    • The cold start problem in Lambda, illustrated with examples of how to mitigate it through optimal RAM allocation and pre-warming functions.
  • The Jets Framework:

    • How Jets simplifies the creation of serverless applications by adopting a Ruby-centric approach rather than a configuration-heavy framework like YAML.
    • Jets efficiently converts Ruby methods into Lambda functions, aiding the development of traditional MVC architectures even in a serverless environment.
  • Development Process and Best Practices:

    • Guidance on how to set up a serverless application using Jets, emphasizing the structure, including app controllers, models, and views.
    • The importance of local testing and continuous integration in the serverless development lifecycle.

Conclusions and Takeaways:

  • Tung emphasizes that Jets enhances Ruby developers' experience in serverless architecture, making it user-friendly and intuitive.
  • The future of serverless development with Ruby looks bright, offering robust solutions that cater to dynamic, scalable application needs.
  • Engaging with the evolving serverless ecosystem is critical for maximizing development efficiency and innovation.

Tung encourages developers to embrace the simplicity and power of Jets for developing Ruby-based serverless applications.

Jets: The Ruby Serverless Framework
Tung Nguyen • Sofia, Bulgaria • Talk

Date: May 17, 2019
Published: unknown
Announced: unknown

Balkan Ruby 2019

00:00:20.300 All right, so the title of my presentation is "Jets: The Ruby Serverless Framework".
00:00:26.519 I wrote it basically just for fun. I wanted to use Ruby in a way that felt like a native serverless framework.
00:00:31.650 So this is the end result of that, and today I'll cover how that works.
00:00:37.649 The emcee did a great job introducing me, so I think it will be a little repetitive now, but here we go.
00:00:43.710 This is the traditional background slide about who I am, my name, what I do, all those fun things.
00:00:51.030 My name is Tung Nguyen, and I run a DevOps consultancy called Blocks, focused mainly on software and media bias in DevOps tooling.
00:00:57.149 I love DevOps tools, and I actually built our written Ruby for my work in the space. I was honored to be recognized as an AWS Container Hero.
00:01:04.320 It was quite a big honor for me last year, as there are only five of us in the world.
00:01:10.049 One of the tools I built is called Roll Call, which helps deploy Docker containers onto ECS.
00:01:15.659 I also have created other tools in this space, such as a CloudFormation template and another one called Jack for Elastic Beanstalk deployments.
00:01:21.330 But today, we'll talk about Jets, this Ruby serverless framework.
00:01:27.180 I think the reason why we're here is that last November, at the re:Invent event, I took this picture: AWS announced official Ruby support for their Lambda runtime.
00:01:33.930 Before that, Ruby was considered a second-class citizen in the serverless world.
00:01:40.439 There were a bunch of other languages supported, like Node.js, Python, Go, and even C#, but no Ruby.
00:01:47.880 I felt that it took them a long time to do this, but finally, when they announced it, I was ecstatic.
00:01:53.490 It felt like an early Christmas present to me, as Ruby has a new release every December.
00:02:00.270 This is a big deal because it puts Ruby in the first-class seat in the serverless world.
00:02:06.869 A good way to explain what a Ruby serverless framework does is to cover some essentials in the serverless world, as this is relatively new to folks not involved here.
00:02:12.900 Let's cover the AWS compute offerings.
00:02:18.450 Currently, in this diagram, on the left side, we have EC2, which stands for Elastic Compute Cloud. Essentially, it's a virtual machine.
00:02:24.870 You can spin those up pretty quickly, in about two or three minutes, giving you full control of the operating system.
00:02:30.150 But with that control, you also have to manage the server yourself.
00:02:36.840 Moving from left to right in the diagram, ECS stands for Elastic Container Service.
00:02:42.209 A very easy way to describe ECS is that it allows you to run Docker containers on EC2 or their Fargate offering.
00:02:48.090 It's essentially a managed service that helps you run Docker containers.
00:02:53.730 To the right, we have Lambda, which is AWS's serverless offering.
00:02:59.400 This is a bit of an oxymoron, as people call it serverless—yet, to be serverless, you need servers.
00:03:05.849 The term is catchy, and many people embrace it, but it doesn't make much sense.
00:03:12.629 Serverless is essentially just a way to run code without managing the server.
00:03:17.760 A better way to describe it is that it is functions as a service.
00:03:23.069 You don't have to worry about the server; AWS manages that for you. You just focus on your code.
00:03:30.750 The benefits of AWS Lambda include no server management, continuous scaling, and a pay-per-request model.
00:03:37.229 The first benefit is that you don’t manage the server. This means you don’t have to worry about security upgrades, OS patching, or instance type upgrades.
00:03:44.639 There are teams of AWS engineers dedicated to these tasks, allowing you to focus on your code.
00:03:50.939 Another benefit is the ability to continuously scale. With EC2, you need to set up auto-scaling rules.
00:03:57.090 Without auto-scaling, even though it's impressive, you still have to configure your rules.
00:04:03.900 With AWS Lambda, it scales for you automatically, which is a significant feat of engineering.
00:04:10.979 Finally, there’s the pay-per-request model, which charges you based on the number of requests and the execution time.
00:04:18.000 This is interesting if you fit within the free tier, where you can get a million requests per month for free.
00:04:23.400 If you want additional staging environments with EC2, you still need to pay a standard fee.
00:04:28.500 However, with AWS Lambda, you can essentially run it for free.
00:04:35.340 I also want to address some of the serverless types; it’s a little hyped.
00:04:42.090 Let's talk about some AWS Lambda considerations. The first is RAM.
00:04:48.420 With AWS Lambda, you can allocate between 128 MB and 3 GB of RAM.
00:04:54.030 In the Ruby world, if you're running a web server, you configure the number of processes and threads.
00:04:59.100 A typical Rails application is about 500 MB of RAM footprint, so for six threads and six processes, you'd use about 3 GB.
00:05:05.310 However, in AWS Lambda, you don’t configure the server; you configure the function.
00:05:11.370 So, if your Ruby process consumes 3 GB of RAM, you might have other issues rather than just RAM.
00:05:17.580 Secondly, let's talk CPU, as people often worry about CPU resources.
00:05:23.850 In my experience, most application limitations tend to be about RAM rather than CPU.
00:05:29.520 In AWS Lambda, CPU is allocated proportionately based on the amount of RAM you allocate to the function.
00:05:36.330 The magic number is around 1.5 GB of RAM, where you get dual CPU cores.
00:05:42.450 Most applications should be fine unless you're doing something intensive like Bitcoin mining.
00:05:48.420 Network speed isn’t a major concern either. If your application is slow, it's often due to the application code.
00:05:54.030 Even with smaller instance types in AWS, the network speed is generally adequate.
00:06:01.020 Lambda functions can execute for a maximum of 15 minutes, which could be a concern for long-running jobs.
00:06:07.890 However, if it's a web request, no user is going to wait for 15 minutes.
00:06:13.680 Another consideration is the code size limit, which is 256 MB for your application code and gem library dependencies.
00:06:18.960 Some Ruby applications can have large gem dependencies, so consider this when designing your application.
00:06:25.290 If your application is more than 256 MB, AWS Lambda might not be a good fit.
00:06:31.770 Now let's discuss cold starts, which is something people often complain about.
00:06:38.640 When the first request comes in, AWS Lambda spins up a container for the service.
00:06:42.309 If you're too conservative with your RAM allocation, this can take about 1 to 1.5 seconds.
00:06:50.000 However, if you allocate at least a gigabyte of RAM, I've seen that cold start times can drop to about 500 milliseconds.
00:06:58.000 Subsequent requests then usually take only a few milliseconds.
00:07:05.000 This reminds me of something in Rails called Russian Doll caching.
00:07:13.000 With dynamic cache keys, if the update time changes, the cache has to be fresh.
00:07:20.000 So if you're generating requests, this takes time and most users do not mind.
00:07:24.000 For a workaround with cold starts, you can pre-warm your functions.
00:07:30.000 One solution in the serverless world is to have a Lambda function that calls your other functions periodically.
00:07:37.000 The Jets framework has pre-warming configured, which I’ll discuss later.
00:07:44.000 Now we need to discuss API Gateway.
00:07:49.000 You can think about API Gateway as a front door to your application.
00:07:55.000 When a user request comes in, API Gateway routes it to a Lambda function and returns the response.
00:08:01.200 API Gateway acts like RESTful API, allowing users to hit the paths using different HTTP verbs.
00:08:07.000 CloudWatch is another essential component.
00:08:13.500 Many of you may know CloudWatch for its centralized logging capabilities.
00:08:18.000 It includes a feature called scheduled event rules, which is basically a way to repeatedly call a function periodically.
00:08:24.600 This acts as a scheduler, managed for you, similar to running a Heroku clock process.
00:08:31.000 To summarize the service components, we have Lambda, which is functions as a service, API Gateway, which is routes as a service, and CloudWatch, which is a scheduling service.
00:08:38.600 When you combine all these components, you can create a traditional Web API architecture using entirely serverless components.
00:08:45.000 User requests come in and hit an API Gateway, triggering multiple Lambda functions.
00:08:52.000 These Lambda functions can interact with two types of backend data storage: DynamoDB and RDS Aurora.
00:08:59.000 DynamoDB is a managed NoSQL database service that scales up and down based on requests.
00:09:06.000 RDS Aurora is a relational database service that also scales according to demand.
00:09:12.000 At the bottom of this architect diagram, CloudWatch handles the scheduled events.
00:09:17.000 Now, let’s go through some quick code examples to explain how Jets works.
00:09:24.000 The console refers to the web browser where you can easily create a function.
00:09:30.000 In the browser, you specify your function name, select Ruby runtime, and click create.
00:09:36.000 Once created, you'll see an IDE in the browser where you can define your Lambda function.
00:09:43.000 The handler has two parts: the name of the file and the Ruby method within it that gets invoked.
00:09:50.000 This Lambda function has a specific signature, accepting two keyword arguments: 'event' and 'context'.
00:09:56.800 The example returns a hash structure with a status code and body.
00:10:03.600 It only takes a few minutes to set this up in the serverless environment.
00:10:09.000 Next, you'll want to set up API Gateway, which can also be done from the browser.
00:10:15.200 You’ll choose the protocol, rest, and create a new API by providing a name.
00:10:22.100 Next, you need to set up your restful resources by specifying the URL path and the HTTP verb.
00:10:28.000 You can associate different requests with a Lambda function, making it very intuitive.
00:10:34.300 Lastly, for CloudWatch Schedule events, you specify a fixed rate, like every 5 minutes.
00:10:41.500 Then you provide the Lambda function as a target, confirming all steps through the interface.
00:10:48.000 In summary, we’ve covered Lambda functions, API Gateway, and CloudWatch scheduled events.
00:10:55.000 Most people prefer to use a configuration management tool for serverless applications.
00:11:01.000 Writing Lambda functions in YAML is common, but I find it less satisfying than writing Ruby.
00:11:07.200 It feels reminiscent of Java development back in the 1990s, where config files were heavily used.
00:11:13.500 So, I wanted to create Jets to solve this problem.
00:11:20.000 Let’s dive into some code examples to see what Jets looks like.
00:11:26.000 Here’s a simple Jets function defined in the app functions folder.
00:11:31.000 It looks like a typical Ruby Lambda function, though not much is happening.
00:11:36.500 However, Jets provides a valuable structure with additional constructs that enhance functionality.
00:11:43.000 For example, in a Jets controller, methods can transform into Lambda functions.
00:11:50.000 If you have public methods in the controller, Jets converts those into Lambda functions.
00:11:57.000 You also have helper methods for functionality like rendering JSON, XML, or HTML.
00:12:03.500 Additionally, the parameters are accessible in a simplified format for easier handling.
00:12:10.000 When using puts in this environment, it logs data to CloudWatch.
00:12:15.000 Next, the routes file in Jets looks similar to traditional routing setups.
00:12:21.000 You define GETs and POSTs, just like you would in a normal Rails application.
00:12:27.000 This translates directly into API Gateway resources.
00:12:33.000 In Jets, you can also define background jobs for your application.
00:12:39.000 Implementing a background job is essential to avoid blocking web requests.
00:12:46.000 You can declare jobs that run periodically to handle tasks asynchronously.
00:12:53.000 These jobs get translated to scheduled event rules in CloudWatch.
00:12:59.000 The Ruby methods transform into Lambda functions, and the routes file corresponds to API Gateway resources.
00:13:05.000 There’s a `jets new` command that gets you started with different modes of operation.
00:13:10.000 The default mode is HTML CRUD, while you can also use API modes for lightweight setups.
00:13:17.000 If you only need a couple of Lambda functions, job mode is ideal for a lightweight structure.
00:13:24.000 With Jets, you just need a few commands to set up your application’s architecture.
00:13:30.000 For an app using an RDS database, the structure includes essential folders like app, controllers, models, and views.
00:13:36.000 The project helps maintain traditional MVC components while working in a serverless environment.
00:13:42.000 Once structure is set up, you can deploy the application quickly using just a few commands.
00:13:50.000 Now, let's take a look at some generated code.
00:13:56.000 Here is an example of the post controller with seven HTTP method actions.
00:14:03.000 This controller uses ActiveRecord for model management and connects to the database seamlessly.
00:14:09.000 Let's run a server locally to test the functionality before deploying.
00:14:15.000 Local testing is essential to ensure that everything works smoothly.
00:14:21.000 You can explore the routes and views that are generated for your application.
00:14:27.000 This approach allows immediate feedback as you work on your application.
00:14:34.000 Once you’ve tested everything locally, you can deploy with confidence.
00:14:40.000 Let’s return to the slides before wrapping up.
00:14:47.000 We covered the AWS API architecture, focusing on setting up endpoints and Lambda functions.
00:14:53.000 The conventional wisdom for serverless development emphasizes minimal canceling.
00:14:59.000 Now, let’s review the Jets components one more time.
00:15:06.000 Ruby methods translate into Lambda functions, while routing files go to API Gateway.
00:15:12.000 Jobs are scheduled and transformed into CloudWatch event rules.
00:15:19.000 The Jets framework greatly simplifies the serverless development process.
00:15:25.000 Let’s consider a common problem: YAML versus Ruby code.
00:15:32.000 While YAML can be lengthy, Ruby keeps your code concise and expressive.
00:15:39.000 As serverless technology matures, it’s crucial to leverage the power of code.
00:15:44.000 There are various integrations supported in the serverless ecosystem.
00:15:50.000 For instance, connecting AWS services like SQS, SNS, and Kinesis enhances functionality.
00:15:56.000 You can create automated workflows that respond dynamically to user actions.
00:16:03.000 For example, a modified security group can trigger a Lambda function that automatically adjusts permissions.
00:16:10.000 The IoT aspect of AWS opens up countless possibilities, allowing devices to connect seamlessly.
00:16:16.000 You can track temperature readings from devices, sending that data to the cloud.
00:16:25.000 For image processing, triggering functions when images are uploaded can automate workflows.
00:16:31.750 Job functions schedule tasks, such as backing up Route 53 records, at defined intervals.
00:16:38.000 Lastly, the essential Jets resource model allows you to transform code intuitively.
00:16:44.000 All the paths in Jets lead to resources, enabling easy customization.
00:16:51.500 Jets also features local server testing with a user-friendly interface.
00:16:57.500 Wrapper commands make it easier to interact with AWS in a streamlined way.
00:17:04.000 Furthermore, both relational databases and DynamoDB are supported for data management.
00:17:11.000 User permissions can be controlled using policies, making it flexible.
00:17:17.500 As we see improvements, functionality expands significantly, impacting development practices.
00:17:25.500 In summary, Jets simplifies Ruby serverless application development, making it user-friendly.
00:17:32.000 The future is promising with serverless solutions leading the way for developers.
00:17:39.000 Thank you very much for your time, and I'll be around for any questions!
Explore all talks recorded at Balkan Ruby 2019
Eli Kroumova
Aaron Patterson
Fernando Mendes
Edouard Chin
Sergei Alekseenko
Tung Nguyen
Soutaro Matsumoto
Kaja Santro
+4