Apache OpenWhisk adds native support for Ruby
Ruby goes Serverless! - Apache OpenWhisk adds native support for Ruby
Ruby has finally become a first class citizen in the Serverless world now that Apache OpenWhisk has added native support for the Ruby Runtime. Thanks to the awesome work from Kei Sawada and the OpenWhisk community, Ruby has been added to the list of languages that are natively supported via OpenWhisk. The current list includes PHP, Go, Swift, Java, JavaScript, Python and Docker Containers.
If you combine Ruby with Serverless’ not having to care about scaling and managing infrastructure you have a combination that is truly optimized for developer happiness.
Running locally
There are many ways you can install Apache OpenWhisk locally or on your cluster. These instructions are for Docker Compose, but there are other options including
Installing via Docker Compose (Mac, Linux & Windows)
My favorite way to install OpenWhisk is via Docker Compose. In my opinion it’s the easiest since the other installations are geared more towards actual production environments and are therefore a little more involved. These following instructions are based on
Make sure you have Git, Docker & Docker Compose installed and then run the following commands.
$ git clone https://github.com/apache/incubator-openwhisk-devtools.git
Cloning into 'incubator-openwhisk-devtools'...remote: Counting objects: 611, done.remote: Compressing objects: 100% (13/13), done.remote: Total 611 (delta 11), reused 17 (delta 9), pack-reused 589Receiving objects: 100% (611/611), 266.75 KiB | 0 bytes/s, done.Resolving deltas: 100% (232/232), done.Checking connectivity... done.
$ cd incubator-openwhisk-devtools/docker-compose
$ make quick-start
Downloading source tar ball.... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 134 0 134 0 0 699 0 --:--:-- --:--:-- --:--:-- 701100 10.4M 0 10.4M 0 0 4273k 0 --:--:-- 0:00:02 --:--:-- 5930kUnpacking tarball.
...
You should get a response like this if your OpenWhisk environment is running well:
ok: whisk auth set. Run 'wsk property get --auth' to see the new value.ok: whisk API host set to 192.168.143.239ok: whisk namespace set to guestwaiting for the Whisk invoker to come up ...creating the hello.js function ...invoking the hello-world function ...adding the function to whisk ...ok: created action helloinvoking the function ...invocation result: { "payload": "Hello, World!" }{ "payload": "Hello, World!" } creating an API from the hello function ...ok: updated action helloinvoking: http://192.168.143.239:9090/api/.../hello/world "payload": "Hello, World!"ok: APIsAction Verb API Name URL/guest/hello get /hello http://192.168.143.239:9090/api/.../hello/worlddeleting the function ...ok: deleted action helloTo invoke the function again use: make hello-worldTo stop openwhisk use: make destroy
Now that we have that running let’s install the wsk
command line interface (cli) so we can start interacting with our OpenWhisk instance.
The easiest way to do that for Mac or Linux is via Homebrew (Mac) or Linuxbrew (Linux). Make sure you have one of these on your system and the we can use brew to install the cli:
$ brew install wsk
==> Installing wsk==> Downloading https://homebrew.bintray.com/bottles/wsk-0.9.0-incubating.high_sierra.bottle.tar.gz######################################################################## 100.0%==> Pouring wsk-0.9.0-incubating.high_sierra.bottle.tar.gz? /usr/local/Cellar/wsk/0.9.0-incubating: 6 files, 11.4MB
If you are on Windows or you don’t want to use brew you can also download a binary release of wsk.
Great, now you have the wsk
cli and have OpenWhisk running locally let’s start building some Serverless Ruby actions!
Let’s move to a different directory just to keep things clean.
$ mkdir ~/my-serverless-actions$ cd ~/my-serverless-actions
Now we can create our action, let’s name the file hello_world.rb
:
All you need to get your Serverless Ruby action working is a method named main
that accepts one argument (that argument is going to be useful later when we start sending different parameters to the serverless action). And a hash as a response. This hash will get converted to JSON and will be the output of your action.
Before we can push the action to OpenWhisk we need to get authentication and the API host pointing to the right place. Thanks to our make quick-start
command we now have a .wskprops
file in our home directory which has all authentication keys and other properties needed to get our wsk
command pointing in the right direction.
Now it’s time to push our Ruby action to our OpenWhisk instance:
$ wsk action create hello-world hello_world.rb -i
ok: created action hello-world
The -i
flag we are using on all our wsk
commands is necessary because Docker Compose creates self signed certificates. In production environments you won’t have to use the -i
or --insecure
flags because you’ll have a validate certificate in place.
Let’s try out our newly minted Ruby action by invoking it via the cli. There are different ways of invoking an action, the default is fire and forget. It’ll be invoked asynchronously and you be able to come back for the response later. But in our case let’s use the --result
flag to make sure we get the response now.
$ wsk action invoke hello-world -i --result
{ "hello": "world"}
We now have our very own Serverless action running natively in Ruby!
Let’s update our hello_world.rb
to accept some parameters.
In this case we are looking for a name
parameter and replacing it with “stranger” if we don’t pass anything in.
Now let’s push our updated action to OpenWhisk.
$ wsk action update hello-world hello_world.rb -i
ok: updated action hello-world
And let’s try running it the same way we did before:
$ wsk action invoke hello-world -i --result
{ "greeting": "Hello stranger!"}
And now let’s pass in a name parameter:
$ wsk action invoke hello-world -i --result --param name World
{ "greeting": "Hello world!"}
Awesome! That all you need to know to start creating some awesome serverless actions in Ruby! Checkout below for some bonus material on how to work with Ruby Gems.
Bonus material
Your actions don’t have to just be single files, you can also package multiple files into one action.
Using Gems
By default the OpenWhisk Ruby runtime comes with a number of Gems installed including jwt, mechanize and ActiveSupport.
You’d use those as you would in any other Ruby project: require "jwt"
.
To demonstrate the use of Ruby Gems in our project let’s create a Lorem Ipsum generator.
Before we start on this, let’s check to make sure you are running a Ruby version over 2.5.0
but below 2.6.0
(same major version as the OpenWhisk’s ruby:2.5 runtime).
$ ruby -vruby 2.5.1
If you aren’t getting 2.5.x
use rbenv or rvm to switch to that version of ruby before you continue.
To start let’s create a new folder named lipsum
.
$ mkdir lipsum$ cd lipsum
First create a Gemfile
to and specify which gems we want to use.
If you don’t have bundler installed you should do that now. Then run bundle
with the standalone
flag.
$ bundle install --standaloneFetching gem metadata from https://rubygems.org/.Resolving dependencies...Fetching betterlorem 0.1.2Installing betterlorem 0.1.2Using bundler 1.16.4Bundle complete! 1 Gemfile dependency, 2 gems now installed.Bundled gems are installed into `./bundle`
Then you need to create your action in main.rb
. Since you’re going to be uploading multiple files this time OpenWhisk will expect the action’s main
method to be in main.rb
.
Now let’s grab all of the Ruby files we want as part of our action and let’s zip them up for easy distribution.
$ zip -r lipsum_generator.zip main.rb bundle adding: main.rb (deflated 20%) adding: bundle/ (stored 0%) adding: bundle/bundler/ (stored 0%) adding: bundle/bundler/setup.rb (deflated 32%) adding: bundle/ruby/ (stored 0%)... adding: bundle/ruby/2.4.0/gems/betterlorem-0.1.2/doc/created.rid (deflated 61%)
If you get an error that your Ruby version is not correct please make sure you switch to ruby version 2.5.x
.
Now we have that we can create our action in OpenWhisk, let’s name it lipsum
.
$ wsk action create lipsum -i --kind=ruby:2.5 lipsum_generator.zip
ok: created action lipsum
Let’s now see if it works by invoking our action.
$ wsk action invoke lipsum -i --result --param length 20
{ "lipsum": "Pharisæorum, et sadducæorum, venientes ad baptismum suum, dixit eis Progenies viperarum, quis demonstravit vobis fugere a ventura ira? Facite ergo."}
Nice! The only thing that had been missing from our APIs has been a Lorem Ipsum text generator and you totally fixed that, well done! Up next: Create an API to RickRoll people!? If you do I’m never gonna give you up!
Conclusion
You’ve been able to setup OpenWhisk locally. And you’ve been able to create a Serverless action in Ruby (my favorite programming language!). You didn’t need to use Docker or any bash injection hacks, because Apache OpenWhisk supports Ruby natively. You’ve been able to use gems to pull in dependencies and you’ve been able to distribute multiple files. Yay!
Personally I think Ruby is probably one of the best languages for Serverless, it’s compact, elegant and easy to read. If you combine Ruby with Serverless’ not having to care about scaling and managing infrastructure you have a combination that is truly optimized for developer happiness.
I’m looking forward to hearing what your experiences are with Ruby and OpenWhisk. Please let me know if you bump into anything confusing as we’ve recently relaunched the OpenWhisk website and are making sure OpenWhisk is as easy to use as possible.