Anatomy of a Lamby Project

Lamby can be installed within legacy applications or bootstrapped from our AWS SAM cookiecutter project. This guide attempts to explain the basics of each & how Lamby works.

How Lamby Works

At its heart, a Rails application on Lambda is still just a normal Rails application. Since Rails is on Rack, the Lamby gem relies on converting any Lambda HTTP event to compatible Rack env objects. We then send that object to your application and pass the result back to the Lambda handler. It is that simple.

def handler(event:, context:)
  Lamby.handler $app, event, context
end

Lamby can convert the following Lambda event integrations to Rack events.

Core Lamby Files

These files are core to Lamby allowing your Rails application to work on AWS Lambda. Some are specific to AWS SAM while others are opinionated files included if you used our Cookiecutter getting started project. These mostly help with Docker.

File - app.rb

The app.rb file is similar to Rails' config.ru for Rack. Commonly called your handler, this file should remain relatively simple and look something like this.

require_relative 'config/boot'
require 'lamby'
require_relative 'config/application'
require_relative 'config/environment'

$app = Rack::Builder.new { run Rails.application }.to_app

def handler(event:, context:)
  Lamby.handler $app, event, context, rack: :http
end

Any code outside the handler method is loaded only once, which includes booting your Rails application. After that, Lamby does all the work to convert the event and context objects to Rack messages that get sent to your Rails application. The details of the AWS Lambda Function Handler in Ruby should be left to Lamby, but please learn about this topic if you are interested.

File - template.yaml

This YAML file at the root of your project describes your SAM application. Don't worry, we have done some heavy lifting for you. But as your application grows you may end up adding resources like S3 Buckets, DynamoDB, or IAM Policies. Please take some time to learn how SAM & CloudFormation works.

Files - Dockerfile, Dockerfile-build, & docker-compose.yml

Your Dockerfile should use one of the AWS provided runtimes from their public ECR repository and typically do a simple copy of your built project. For example:

FROM public.ecr.aws/lambda/ruby:2.7
COPY . .
CMD ["app.handler"]

The Dockerfile-build facilitates both the local development and the build environment to prepare the copy above. This follows a typical good practice for Docker called multi-stage builds. We recommend using SAM's build images (ex: amazon/aws-sam-cli-build-image-ruby2.7) for your development needs. Installing additional tooling like a SAM version and JavaScript for compiling assets should be done in this image. All docker compose commands leverage this image.

Files - bin

Because we encourage use of the Lambda docker containers using the Docker files above, we include a host of bin scripts that make development easy for you. All files with a leading _ should be run in the container. For example, bin/server is just a docker-compose run command to bin/_server. Overall, here is what you will find in our cookiecutter project.

Our SAM Cookiecutter's Features

Our cookiecutter makes starting a Rails application so easy, you may have missed some of the interesting things we have done for you. Here is a small list.

Installing for Legacy Applications

Rails has been on Rack v2 since Rails v5.0. So in theory, any v5.0 or newer application can work with Lamby.

Add the Lamby gem to your Gemfile. We use require: false here so Lamby is only loaded in your app.rb. This keeps your development/test logs working vs. using STDOUT.

gem 'lamby', require: false

Lamby provides a simple Rake task to install starter files needed to use AWS Lambda for your application. In this example, we are using the default API Gateway HTTP API installer but you can also use Lamby with API Gateway's REST API or an Application Load Balancer.

$ ./bin/rake -r lamby lamby:install:http
# Alternatives
$ ./bin/rake -r lamby lamby:install:rest
$ ./bin/rake -r lamby lamby:install:alb

This task will install app.rb, template.yaml, and starter bin files. Please review our cookiecutter's build scripts for examples of what you may want to include as well.

Inspiration

Thanks to the projects and people below which inspired our code and implementation.

Other small details which Lamby helps with.