The quickest & easiest way to develop AWS Lambda functions that use Ruby gems
Although there are some nifty frameworks for building and managing AWS Lambda functions using Ruby, unless the project is quite complex I like a simple local-to-AWS development flow, without any framework magic obscuring what’s actually happening in my code.
This is probably the simplest way to get up and running developing locally for AWS Lamda functions that need to use common gems such as “rest-client”. It is modeled after: https://www.stevenringo.com/ruby-in-aws-lambda-with-postgresql-nokogiri/ but simplified.
You need an AWS account, and Docker, period. (Don’t even need the AWS CLI command line utility.)
In browser:
1. Create a default 'hello world' lambda function in your aws lambda console
It sets up intelligent default for roles etc.
I like to set concurrency to 1 while developing.
In the Mac terminal:
2. Create a docker folder with a dockerfile that uses an aws lambda image
$ mkdir aws-lambda-docker $ cd aws-lambda-dockerIf using postgres (like the article above this was based on) it'll need extra stuff, this example below is just the simplest Dockerfile, to let you use ruby gems.
# be sure the ruby version is same as what aws lambda currently offers # Dockerfile FROM lambci/lambda:build-ruby2.7 RUN gem update bundler CMD "/bin/bash"
3. Create tagged docker container, your own local "AWS Lambda in a Box" that you can re-use for all your Ruby-with-gems Lambda projects:
I’m building a container for aws lambda ruby v27 so I use that for the tag:
$ docker build -t awsruby27 .
4. Make a Project directory
$ mkdir awsstuff $ cd awsstuff
5. Create your lambda_function.rb code
We’ll use two gems, one that needs to be compiled with native extensions (nokogiri) and one that does not (rest-client).
# lambda_function.rb require 'json' require 'rest-client' require 'nokogiri' def lambda_handler(event:, context:) url = "https://api.myip.com" puts "use rest-client ruby gem" html = "<html><title>The Title</title><body>The Body</body></html>" parsed_data = Nokogiri::HTML.parse(html) puts parsed_data.title rr = RestClient::Request.execute :method => :get, :url => url, :ssl_version => 'SSLv23' result = "Title check: #{parsed_data.title} and remote api returned #{rr.body}" { statusCode: rr.code, body: result } end
6. Create your Gemfile
# Gemfile source "https://rubygems.org" gem "rest-client" gem "nokogiri"
7. Inside the project folder, run the Lambda ruby container:
$ docker run --rm -it -v $PWD:/var/task -w /var/task awsruby27
Inside the docker container:
8. Bundle your project
Only needed when you create or modify the Gemfile:
bash-4.2# bundle install --path vendor/bundle --clean
9. Test your handler code
Via Ruby’s -e option to execute a string containing the ruby code to require & invoke a function:
bash-4.2# ruby -e "require 'lambda_function'; puts lambda_handler(event: nil, context: nil)" # output: use rest-client ruby gem The Title {:statusCode=>200, :body=>"Title check: The Title and remote api returned {\"ip\":\"xxx.xxx.xxx.xxx\",\"country\":\"United States\",\"cc\":\"US\"}"}
Or interactively, via irb:
bash-4.2# irb > require 'lambda_function' > lambda_handler(event: nil, context: nil) # output: use rest client ruby gem The Title {:statusCode=>200, :body=>"Title check: The Title and remote api returned {\"ip\":\"xxx.xxx.xxx.xxx\",\"country\":\"United States\",\"cc\":\"US\"}"} > exit bash-4.2# exit
10. Back in Terminal, package the zip file
$ rm -f deploy.zip ; zip -q -r deploy.zip .
In AWS console:
11. Upload your working zip file deployment to the lambda function
In aws console, on the existing lambda function, on CODE tab, use UPLOAD FROM button on right and upload zip fle
12. Test it on Lambda
Now you have an AWS Lambda function in Ruby, which can use arbitrary Ruby gems, even native-extensions gems like nokogiri (which works on AWS since you compiled your Ruby bundle inside a docker container based on the AWS ‘build’ image for Ruby).
A few notes about deployment size...
The bundle’s deployment size increases significantly if you add certain native-extension gems such as nokogiri, and if the deployment package exceeds some limit you will not be able to view the code on the AWS Lambda console and will see this message instead:
The deployment package of your Lambda function "test2" is too large to enable inline code editing. However, you can still invoke your function.
The code still runs on Lambda, only the code view/edit is disabled when the package is too large.
For your NEXT projects, simply start at step 4.
You’ve already created your Lambda-in-a-Box docker container so simply create a project folder, write your lambda_function.rb and Gemfile, then use your already-built docker container to run and text your code.