今週の Ruby Weekly でこんな記事が紹介されていました:
『Serverless Ruby on AWS Lambda with the Jets framework』(Jetsフレームワークを使った AWS Lambda でのサーバーレス Ruby)
AWS Lambda で Ruby がサポートされたのはわりと最近の話ですが(2018年11月: Announcing Ruby Support for AWS Lambda)、「Jets」というサーバーレス用のRubyフレームワークを使えば、短時間で AWS Lambda にデプロイできるみたいです。
面白そうだと思ったので少し触ってみました。
Ruby on Jets とは?
Jetsは、サーバーレスサービスを簡単に構築・デプロイするためのRubyフレームワークです。AWSサービスとのシームレスな連携が売りのようですね。
公式ページでは、次のように説明されています。
Ruby on Jets allows you to create and deploy serverless services with ease, and to seamlessly glue AWS services together with the most beautiful dynamic language: Ruby.
ざっと見た感じ、AWS Lambdaへのデプロイに特化した簡易的なRailsといった印象です。
Ruby on Jets の設計
Jets で AWS Lambda にデプロイした場合、設計は次のようになります。
Ruby on Jets をデプロイしてみる
Ruby on Jets の AWS Lambda へのデプロイがどれぐらいシームレスなのか、実際に検証してみます。
参考にした記事は次のとおりです:
Ruby on Jets アプリの作成
GETリクエストで「Hello from Ruby on Jets」を返すだけのシンプルなAPIアプリを用意します。
インストール
Ruby のバージョンは 2.5.0 です。
$ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin18]
まずは Jets をグローバルにインストールします。
$ gem install jets
インストールできました。
$ jets -v
1.9.1
プロジェクトの作成
rails
コマンドのように jets new YOUR_APP_NAME
でプロジェクトを作成できます。
今回は API で、かつ、DB不要の簡易アプリなので、オプションに --mode api --no-database
を渡します。
$ jets new hello_ruby_on_jets --mode api --no-database
作れるファイルは次のような感じ。ほぼ Rails ですね。
your_app_name
├── app
│ ├── controllers
│ ├── helpers
│ ├── jobs
│ └── models
├── config
├── db
├── public
├── spec
├── config.ru
├── Gemfile
├── Gemfile.lock
├── Procfile
├── Rakefile
└── README.md
サーバを起動させてみます。
$ jets server
http://127.0.0.1:8888/
でサーバが立ち上がります。
アプリの実装
Greetings コントローラーを作成します。
$ jets g controller Greetings index
create app/controllers/greetings_controller.rb
route get 'greetings/index'
index アクションにプレーンテキストを返す処理を書きます。
class GreetingsController < ApplicationController
def index
render plain: 'Hello from Ruby on Jets!'
end
end
ルーティングはこんな感じ。
Jets.application.routes.draw do
get 'greetings', to: 'greetings#index'
root "jets/public#show"
# The jets/public#show controller can serve static utf8 content out of the public folder.
# Note, as part of the deploy process Jets uploads files in the public folder to s3
# and serves them out of s3 directly. S3 is well suited to serve static assets.
# More info here: http://rubyonjets.com/docs/assets-serving/
any "*catchall", to: "jets/public#show"
end
試しにサーバを起動させて curl
を叩いてみます。
$ jets serve
$ curl http://localhost:8888/greetings
Hello from Ruby on Jets!
問題なさそうですね。
AWS Lambda でのデプロイ
作ったアプリを AWS Lambda にデプロイしてみます。
必要なステップは「1. 認証キーの発行」と「2. デプロイ」です。
1. 認証キーの発行
AWSにデプロイするには認証キーが必要です。
ポリシーの作成
AWSのコンソールから「IAM」のページに飛び、新しくポリシーを作成します。
JSONタブを選択し、公式ドキュメント「Minimal Deploy IAM Policy」に提示されている次の権限設定をコピペします。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"apigateway:*",
"cloudformation:*",
"dynamodb:*",
"events:*",
"iam:*",
"lambda:*",
"logs:*",
"route53:*",
"s3:*"
],
"Resource": [
"*"
]
}
]
}
ユーザーの作成
ポリシーの作成後、新規ユーザーを作成します。
「プログラムによるアクセス」を選択します。
そして、「既存のポリシーを直接アタッチ」を選び、先ほど作成したポリシーを適用します。
ユーザーの作成が終わると、「アクセスキー ID」と「シークレットアクセスキー」が発行されるので、それらを保管します。
2. デプロイ
ここからが Jets の最大の強み。
なんと、わずか1行でAWS Lambdaにデプロイできます。
認証キーを持たせて jets deploy
するだけです。
$ AWS_ACCESS_KEY_ID=YOUR_ID AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY jets deploy
AWS_ACCESS_KEY_ID
: アクセスキー IDAWS_SECRET_ACCESS_KEY
: シークレットアクセスキー
コマンドを実行するとデプロイが始まります。
Deploying to Lambda hello-ruby-on-jets-dev environment...
Building CloudFormation templates.
Deploying CloudFormation stack with jets app!
10:17:57PM CREATE_IN_PROGRESS AWS::CloudFormation::Stack hello-ruby-on-jets-dev User Initiated
10:18:01PM CREATE_IN_PROGRESS AWS::S3::Bucket S3Bucket
10:18:02PM CREATE_IN_PROGRESS AWS::S3::Bucket S3Bucket Resource creation Initiated
10:18:22PM CREATE_COMPLETE AWS::S3::Bucket S3Bucket
10:18:25PM CREATE_COMPLETE AWS::CloudFormation::Stack hello-ruby-on-jets-dev
Stack success status: CREATE_COMPLETE
(省略)
10:23:37PM UPDATE_COMPLETE_CLEANUP_IN_PROGRESS AWS::CloudFormation::Stack hello-ruby-on-jets-dev
10:23:38PM UPDATE_COMPLETE AWS::CloudFormation::Stack hello-ruby-on-jets-dev
Stack success status: UPDATE_COMPLETE
Time took for stack deployment: 2m 29s.
Prewarming application.
API Gateway Endpoint: https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/
最終行に API Gateway Endpoint
が表示されれば、デプロイ完了です。
10:17:57PM
に開始して 10:23:38PM
に完了したので、デプロイにかかった時間は5分ちょっと。これはかなりお手軽じゃないでしょうか?
試しに curl
でエンドポイントを叩いてみます。
$ curl https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/greetings
Hello from Ruby on Jets!
ちゃんと動いていますね。
AWS Lambda をコンソールで確認
デプロイしたアプリを AWS Lambda のコンソールから確認します。
エンドポイントに us-east-1
とあるので、リージョンは「バージニア北部」を選択します。
デプロイしたアプリを確認できました。
感想
AWS Lambda は詳しくないですが Jets を使うと、わずか1行でサクッとデプロイできました。
Lambda の設定は Jets に依拠して、Ruby のコードだけに集中できるのが良いですね。
Ruby on Rails を知っていれば、学習コストはほとんどないので、ちょっとしたサーバーレスアプリの開発に使えるんじゃないかな、と思いました。