03/14/2021

Experimenting with Serverless Ruby - Part 1

I've been wanting to experiment with serverless ruby and AWS lambda functions for a while now. This series of posts will mostly just be my own notes from these experiments.

I'm new to serverless/AWS Lambda, so in this first part, the goal is simply going to be to build and deploy a hello world lambda function following the AWS docs. Specifically, I'll be following this example using AWS SAM. You'll need to install the AWS SAM CLI in order to follow along; you can find the install options here to set that up.

Creating a new AWS Lambda Function

Using the SAM CLI, the first thing we need to do is run sam init to download a sample app that we can use:

➜ sam init

This command will lead to some prompts about how you want to set up and configure your app. Here are the settings I selected to configure my app with ruby:

My specific settings that I'm choosing for this are AWS Quick Start Templates for the template, Zip for the package type, ruby2.7 for the runtime, and Hello World for the application template.

After running through this you should see that a new directory has been created. In my case because I didn't provide a name it's just called sam-app. So let's go ahead and cd into the app:

➜ cd sam-app

If we take a look in the app you can see a number of files that were created by the init command. What we are interested in for now is the code that was created for us in hello_world/app.rb:

This file contains the actual code that gets executed for our lambda function. You can see that currently all this function is doing is returning a json payload with the message 'Hello World!' in it:


def lambda_handler(event:, context:)
  ...

  {
    statusCode: 200,
    body: {
      message: "Hello World!",
      # location: response.body
    }.to_json
  }
end

sam build

So now, following the docs, we can try running the sam build command. According to the AWS docs, this command "builds any dependencies that your application has, and copies your application source code to folders under .aws-sam/build to be zipped and uploaded to Lambda." So let's run that:

➜ sam build

If your build fails here with an error like this:

Error: RubyBundlerBuilder:RubyBundle - Bundler Failed

check and make sure that your local ruby version matches the ruby version we are using in our app. In this case, the ruby version is 2.7, so you may need to do something like rbenv local 2.7.0 to make sure your local ruby version matches (this command will vary depending on what you use for version management).

Once you get a successful build, it should look something like this:

Deploying Our Lambda Function

With the above steps done, and following along with the AWS docs, it looks like we are ready to try deploying our lambda function to the AWS cloud. To do this we just need to run the deploy command like so:

➜ sam deploy --guided

Running this command will result in a number of prompts with configuration options for your app. You can take a look back at the AWS docs linked above for more details on the specific prompts and options you will get during this step.

Once you make it through all of those, your app should deploy, and then you should see some outputs in your terminal which will include a url:


-------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
-------------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               ...

Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://asdfjkl.execute-api.us-west-2.amazonaws.com/Prod/hello/

Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               ...
-------------------------------------------------------------------------------------------------------------------------------------------------
        

At this point, your lambda function has been deployed to the AWS cloud, and you should be able to test it out now by making a curl request to that url:


➜ curl https://asdfjkl.execute-api.us-west-2.amazonaws.com/Prod/hello/
{"message":"Hello World!"}
        

Pretty cool!

Running Lambda Functions Locally

If you have docker installed, you can run your lambda function locally by running the command sam local start-api:

➜ sam local start-api

Now you should be able to run your lambda function locally just like we did in the production example above. If you followed the above steps, your local endpoint will be http://localhost:3000/hello. Here's an example making a requst using Insomnia:

Conclussion

It's important to note that in the above example, our API gateway was configured without authorization when we deployed our function to the AWS cloud. This means the url to execute our function is public. Make sure to read this portion of the AWS docs that this article follows to learn more about this topic.