It’s relatively easy to work with AWS Lambda, but preparing and deploying your code is not as straightforward as it could be. Here’s how to use Ruby_Lambda, a new tool that cuts repetition and makes life easier.
AWS Lambda is a service that lets you build complex microservice-like web applications without building or maintaining any infrastructure.The service used to only support languages such as Python, Java and Javascript, but in November 2018 Ruby support was added too.
Recently, while building Twitter bots and other apps, I’ve found myself writing the same command line configurations over and over. It’s boring and frustrating and potentially a barrier to entry for people just starting out.
I set out to create a tool that would remove the repetition and make things easier to figure out. The result is Ruby-Lambda, a tool I created that helps develop, locally test, and deploy serverless Ruby apps to AWS Lambda.
This tool cuts out a lot of the manual work – I find I’m able to focus on solving the problem rather than writing the same code repeatedly.
Looking for expert guidance or developers to work on your project? We love working on existing codebases – let’s chat.
Here’s how to make Ruby_Lambda work for you.
How to install the Ruby_Lambda tool
To install the gem, simply run this in the terminal:
$ gem install ruby_lambda
If you’d like to check out the code, here’s the Github Repo.
How to use the tool
Scaffolding your app structure
$ ruby-lambda init
This command initialises the .gitignore
, config.yml
, env
, event.json
, lambda_function.rb
, Gemfile
, .ruby-version
files.
event.json
is where you keep mock data that will be passed to your function when theexecute
command runs.config.yml
contains some default configuration for your function.env
will be renamed to.env
after the init command runs, and will containAWS_ACCESS_KEY
andAWS_SECRET_ACCESS_KEY
. You will need these to be able to deploy your function.
Please have a read of the config.yml
and update any of the default configurations to better suit your function.
Running a function locally
$ ruby-lambda execute
This command is used to invoke/run the function locally.
Options:
-c, --config=CONFIG # Default: config.yml
-H, --handler=HANDLER
Example use cases:
$ ruby-lambda execute -c=config.yml
$ ruby-lambda execute -H=lambda_function.handler
The handler function is the function AWS Lambda will invoke/run in response to an event. AWS Lambda uses the event argument to pass in event data to the handler. If the handler
flag is passed with execute, this will take precedence over the handler function defined within the config.yml
.
def handler(event:, context:)
{ statusCode: 200, body: JSON.generate('Hello from Ruby Lambda') }
end
The execute
command retrieves the values stored in the event.json
file and passes them to your handler function.
Creating a deployable zip
$ ruby-lambda build
This command creates a zipped file ready to be published on Lambda. A new folder called ‘builds’ will be created and all zips will be stored in there.
Options:
-n, --native-extensions flag to pass build gems with native extensions
-q, --quiet
A note on native extensions
This article from Pat Shaughnessy covers what native extensions are and how they work.
Basically, building a native extension means compiling C code into the platform and environment specific machine language code. So, if you run bundle install — deployment on your local machine running MacOS, the C code is compiled for MacOS and stored in vendor/bundle. As AWS lambda is a Ubuntu machine, not MacOs, it won’t work.
To build gems with native extensions use -n
flag when you run this command. Doing so will run a dockerized bundle with deployment flag within a Lambda image – this will download the gems to the local directory instead of to the local systems Ruby directory, using the same OS environment as Lambda so that it installs the correct native extensions. This ensures that all our dependencies are included in the function deployment package and the correct native extensions will be called.
Deploying and publishing your function
$ ruby-lambda deploy
The deploy command will either bundle install your project and package it in a zip, or accept a zip file passed to it, then upload it to AWS Lambda.
Options:
-n, --native-extensions flag to pass build gems with native extensions
-c, --config=CONFIG path to the config file, defalt is config.yml
-p, --publish if the function should be published, default is true
-u, --update default to true, update the function
-z, --zip-file=ZIP_FILE path to zip file to create or update your function
-q, --quiet
By default the deploy
command will attempt to create the function with your config – if the function already exists an error will be thrown. To update an existing function simply pass the -u
flag.
When you publish a version, AWS Lambda makes a snapshot copy of the Lambda function code (and configuration) in the $LATEST version. A published version is immutable. That is, you can’t change the code or configuration information.
The new version has a unique ARN that includes a version number suffix. AWS recommends that you publish a version at the same time that you create your Lambda function, or update your Lambda function code. So by default, all deploy will be versioned – if you do not want this, use the -p=false
flag.
When you run the deploy command, it will prepare the latest state of your function and zip it up, basically running the build command. If you have already built your zip, use the -z
flag to set the path to it.
Want to contribute?
I hope this tool proves useful for you – it’s definitely made my work a lot easier.
Keep an eye out for future posts on how to use the tool with specific technologies, including Twitter bots, basic machine learning and custom APIs.
New ideas, features, bug reports and pull requests are welcome on GitHub. Check the read me for the development guide.