Help us understand the problem. What is going on with this article?

Ruby 製サーバーレスフレームワークの Jets を検証してみたら、Rails ライクに使えていい感じだった

More than 1 year has passed since last update.

はじめに

2018年11月29日、AWS Lambda で Ruby が正式にサポート されましたね。サーバーレスアプリケーションを試そうとしている Rubyist の方々には、念願のアップデートだったのではないでしょうか。

しかし、Lambda で Ruby がサポートされたとはいえ、どこから手をつけていいかわからない!という方が多いと思います。僕自身もそうでした。。

そんな中、Ruby 製のサーバーレスフレームワーク、Jets という gem を見つけました。どんな形で使えるか検証したところ、簡単にサーバーレスアプリケーションに入門できそうな印象を持ちました。

この記事では、そんな Jets について、簡単な概要と、とっかかりとなるサンプルアプリケーションの作成・デプロイの検証結果についてまとめてみました。

Jets とは

image.png

Jets は、Ruby 製のサーバーレスアプリケーションフレームワークです。Ruby でサーバーレスアプリケーションを実装することができます。

また Jets にはアプリケーションをビルドし、AWS Lambda にデプロイする機能が含まれているため、コマンドライン上で手間をかけずビルド・デプロイすることが可能です。

Jets の思想

Jets の利用方法をこの後書いていきますが、Jets で使うコマンドやコードは、Ruby on Rails とよく似ているところが多いです。

コマンド・コードを抜粋してみましたが、非常に Rails と似ていることがわかるのではないでしょうか。

jets new
jets generate scaffold
jets db:migrate
jets server
jets console
jets deploy
jets routes
jets call
jets status
jets url
jets delete
class PostsController < ApplicationController
  def index
    # renders Lambda Proxy structure compatiable with API Gateway
    render json: {hello: "world", action: "index"}
  end

  def show
    id = params[:id] # params available
    # puts goes to the lambda logs
    puts event # raw lambda event available
    render json: {action: "show", id: id}
  end
end

(参考:http://rubyonjets.com/#page-top)

Jets の作者の Tung Nguyen さんは、 Jets の紹介ブログポスト で以下のようにコメントしています。

I love working with Rails, Ruby and AWS; and wanted to work with something similar in the serverless world. So I built Jets.

(意訳) 私は Rails、Ruby、AWS を使うことが好きで、サーバーレスの世界でも似たようなものを使いたいと思っていました。だから Jets を作りました。

このコメントからも、Jets が Rails の思想に影響を受けていることがわかりますね。

Rails をよく使っている方々でしたら、Rails の設計や考え方を流用して理解できるところが多く、使い方のキャッチアップもしやすいですし、設計で悩む時間も短縮できそうです。

Jets アーキテクチャ概要

Jets の README によると、Jets を利用する上でキーとなっているのが、AWS Lambda と API Gateway のようです。以下にそれぞれの役割を簡単にまとめます。

AWSサービス 役割
AWS Lambda Fuction as a Service として扱う。Jets では AWS のインフラの詳細を気にせず Lambda Function をアップロード・実行することが可能
API Gateway Lambda Function へのルーティングを担う。RESTful な URL エンドポイントを、Lambda Function に紐付ける

イメージ図を Jets 公式ドキュメントから引用します。API Gateway がそれぞれの Lambda Function に対し、RESTful な URL を提供していることがざっくりつかめるのではないでしょうか。

jets-web-architecture.png

(画像引用元:http://rubyonjets.com/#page-top)

Quick start で Jets アプリケーションを動かす

それでは実際に Jets アプリケーションを動かしてみたいと思います。Jets 公式ドキュメントの Quick Start を試していきますが、以下2パターンで試していきます。

  1. ローカル環境で動かす
  2. AWS 環境で動かす

環境情報

  • Mac OS X 10.13.6
  • ruby 2.5.1
  • mysql Ver 8.0.12 for osx10.13 on x86_64 (Homebrew)

1. ローカル環境で Jets を動かす

まず AWS の環境にデプロイする前に、ローカル環境で Jets アプリケーションを使えるようにします。

Jets インストール

まず gem をインストールします。コマンド一発ですね。

gem install jets

jets new:アプリケーション作成の下準備

次に、Jets アプリケーションの土台を作ります。rails new っぽいですね。

jets new jets-sandbox
cd jets-sandbox

実行時の出力を適宜省略しながら記載します。ファイル作成や gem install といった諸々の処理を実行しています。

# ファイル作成
Creating new project called jets-sandbox.
      create  jets-sandbox
      create  jets-sandbox/.env.development
      create  jets-sandbox/.env.test
      create  jets-sandbox/.env
      create  jets-sandbox/.gitignore
      create  jets-sandbox/.jetskeep
      create  jets-sandbox/.rspec
      create  jets-sandbox/Gemfile
      create  jets-sandbox/Procfile
      create  jets-sandbox/README.md
      create  jets-sandbox/Rakefile
      create  jets-sandbox/app/controllers/application_controller.rb
      create  jets-sandbox/app/helpers/application_helper.rb

(中略)

# gem インストール
Fetching gem metadata from https://rubygems.org/........
Resolving dependencies...
Fetching rake 12.3.2
Installing rake 12.3.2
Fetching concurrent-ruby 1.1.4
Installing concurrent-ruby 1.1.4


# yarn で JavaScript 関連ライブラリ インストール
Installing all JavaScript dependencies
         run  yarn add @rails/webpacker coffeescript@1.12.7 from "."

(中略)

# git commit
Initialized empty Git repository in 
 (中略)
 49 files changed, 7094 insertions(+)

Congrats 🎉 You have successfully created a Jets project.

Cd into the project directory:
  cd jets-sandbox

To start a server and test locally:
  jets server # localhost:8888 should have the Jets welcome page

Scaffold example:
  jets generate scaffold Post title:string body:text published:boolean

To deploy to AWS Lambda, edit your .env.development.remote and add a DATABASE_URL endpoint.
Then run:

  jets deploy

jets generate scaffold:アプリケーションの雛形を作る

Jets アプリケーションの雛形を作ります。こちらも rails generate scaffold とよく似ていますね。

jets generate scaffold Post title:string

     invoke  active_record
      create    db/migrate/20180925233914_create_posts.rb
      create    app/models/post.rb
      invoke  resource_route
       route    resources :posts
      invoke  scaffold_controller
      create    app/controllers/posts_controller.rb
      invoke    erb
      create      app/views/posts
      create      app/views/posts/index.html.erb
      create      app/views/posts/edit.html.erb
      create      app/views/posts/show.html.erb
      create      app/views/posts/new.html.erb
      create      app/views/posts/_form.html.erb
      invoke    helper
      create      app/helpers/posts_helper.rb

jets db:create db:migrate:DB のマイグレーション

DB のマイグレーションを行います。こちらもrails db:create db:migrate とほとんど同じです。

jets db:create db:migrate

Created database 'jets-sandbox_development'
Created database 'jets-sandbox_test'
== 20181230024506 CreatePosts: migrating ======================================
-- create_table(:posts) -> 0.0079s 
== 20181230024506CreatePosts: migrated (0.0080s)=============================
補足: DBマイグレーションでエラーが起きた場合は

もし以下のエラーが出た場合は、MySQL 5系→MySQL 8系にアップグレードしたことが原因の可能性が高いです。

ERROR 1449 (HY000): The user specified as a definer ('mysql.infoschema'@'localhost') does not exist

以下コマンドを実行し、MySQL のシステム情報をアップデートしましょう。

mysql_upgrade -u root

(参考:https://bugs.mysql.com/bug.php?id=91432)

jets server:アプリケーション起動

いよいよ Jets アプリケーションを起動します。

jets server

=> bundle exec shotgun --port 8888 --host 127.0.0.1
Jets booting up in development mode!
== Shotgun/WEBrick on http://127.0.0.1:8888/
[2018-12-30 12:11:15] INFO  WEBrick 1.4.2
[2018-12-30 12:11:15] INFO  ruby 2.5.1 (2018-03-29) [x86_64-darwin17]
[2018-12-30 12:11:15] INFO  WEBrick::HTTPServer#start: pid=14592 port=8888

http://localhost:8888 にアクセスすると、以下のような画面が表示されます。

image.png

そして scaffold で作成した Post モデルの CRUD 操作は、http://localhost:8888/posts にアクセスして行います。

アクセスの前に、webpack でJavaScript のライブラリをバンドルしてからアクセスしましょう。

webpack -w

それぞれ URL にアクセスすると、遷移が確認できると思います。

index: http://localhost:8888/posts

image.png

new: http://localhost:8888/posts/new

image.png

show: http://localhost:8888/posts/1

image.png

2. AWS Lambda にデプロイ

ローカル環境での確認ができたので、AWS 環境に Jets アプリケーションをデプロイしましょう。

AWS シークレットキー設定

まず、Jets アプリケーションをデプロイする AWS アカウントのシークレットキーを設定します。

今回は検証のため、Administrator 権限の IAM ユーザーのシークレットキーを使いましたが、本番環境で使う場合などは、適切な IAM 権限で絞って使う必要がありそうですね。

vim ~/.aws/credentials

aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

jets deploy:アプリケーションを AWS 環境にデプロイ

それではデプロイを実行してみましょう。以下コマンド一発でOKです。

jets deploy


(中略)

Time took for stack deployment: 4min 41s.
Prewarming application.
API Gateway Endpoint: https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/

コマンドを実行すると様々な処理が走ります。

その後、出力の最後に表示される API Gateway のURL https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/ にアクセスし、アプリケーションの画面が表示されるか確認してください。

image.png

jets deploy コマンドでは、アプリケーションのビルドからデプロイまで自動で実行してくれます。

  • Lambda 用にアプリケーションの zip ファイルを作成
  • S3 に zip ファイルをアップロード
  • API Gateway の設定、Lambda Function を CloudFormation 経由で作成実行

AWS のコンソールを確認すると、それぞれ AWS リソースが作成されていることがわかると思います。

S3

image.png

API Gateway

image.png

Lambda

image.png

CloudFormation

image.png

RDS MySQL データベース作成

これでアプリケーションのデプロイ自体はできましたが、 Post モデルの CRUD 画面の確認はまだできない状態です。

そのため、AWS 環境用のデータベースとして、RDS で MySQL データベースを作成・設定することで、Post モデルの CRUD 画面も確認できるようにします。

※ Post モデルの CRUD 画面確認は不要で、デプロイ確認のみで十分な場合は、以降の手順は飛ばしてもらってOKです。

データベース作成手順は AWS の RDS ユーザーガイドが詳しいのでそちらをご参照ください。

設定内容はほとんどデフォルトにしましたが、最低限修正したところは以下の通りです。

項目 設定内容
MySQLバージョン MySQL 8.0.11
インスタンスサイズ db.t2.micro
インスタンス名 jets-sandbox-development-instance
データベース名 jets_sandbox_development
ユーザー名 jetssandboxuser
パスワード 任意
パブリック接続 可能

検証において考慮する点を減らすため、Lambda Function はパブリック通信で RDS データベースに接続することを想定します。(同一プライベート VPC 内に Lambda、RDS を含めればできそうですが、今回は検証対象外とします)

そこで、 RDS データベース作成後、Lambda Function からパブリック通信経由で RDS データベースにアクセスできるようにするため、セキュリティグループの設定を修正します。

RDS に設定された セキュリティグループのインバウンドを、任意の IP (0.0.0.0/0) に設定し直してください。

image.png

Jets アプリケーションの環境変数ファイル修正

Jets アプリケーションが RDS データベース接続情報を認識できるよう、データベース設定を修正します。

まず .env.development.remote というファイルを作成します。

cp .env.development .env.development.remote

ファイル内で、RDSデータベース情報を以下のように設定します。

env.development.remote
ENV_DEVELOPMENT_KEY=example1
DB_NAME=jets_sandbox_development
DB_USER=jetssandboxuser
DB_PASS=EXAMPLEPASSWORD
DB_HOST=jets-sandbox-development-instance.XXXXXXXXXXXX.us-east-1.rds.amazonaws.com

RDSデータベースに対しマイグレーション実行

RDSデータベースに対し、マイグレーションを実行します。

以下2つの環境変数の指定しつつコマンドを実行することで、.env.development.remote を参照するようになります。

  • JETS_ENV: 環境を指定
  • JETS_ENV_REMOTE: リモートの環境かどうかを指定
JETS_ENV=development JETS_ENV_REMOTE=1 jets db:create db:migrate

jets console: コンソールでアプリケーションのデバッグ

もし接続がうまくいかないよう場合は、jets console を使ってデバッグ確認してみましょう。

rails console のような形で、Post.all のようにアプリのモデルの状態を確認できます。

JETS_ENV=development JETS_ENV_REMOTE=1 jets console


Jets booting up in development mode!
irb(main):001:0> Post.all
=> #<ActiveRecord::Relation [#<Post id: 1, title: "test", created_at: "2018-12-30 05:24:18", updated_at: "2018-12-30 05:24:18">]>
irb(main):002:0>

再度デプロイ・画面確認

最後に再度デプロイします。

jets deploy

デプロイ後、https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/posts にアクセスできるか確認してください。

image.png

jets delete︰サンプルアプリケーションを削除

検証で使ったアプリケーションを最後に削除したい!という場合は、jets deleteコマンドで関連する AWS リソースを一括削除できます。

RDS データベースは、直接 RDS コンソールからインスタンスを削除してください。

jets delete

Deleting project...
Are you sure you want to want to delete the jets-sandbox-dev project? (y/N)
y
First, deleting objects in s3 bucket jets-sandbox-dev-s3bucket-uio563jvqwra
Deleting jets-sandbox-dev...
03:27:22PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack jets-sandbox-dev User Initiated
03:27:23PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack JetsPreheatJob
03:27:23PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack ApiDeployment20181230142056
03:27:34PM DELETE_COMPLETE AWS::CloudFormation::Stack ApiDeployment20181230142056
03:27:35PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack PostsController
03:27:35PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack JetsPublicController
03:27:58PM DELETE_COMPLETE AWS::CloudFormation::Stack JetsPublicController
03:28:10PM DELETE_COMPLETE AWS::CloudFormation::Stack PostsController
03:28:11PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack ApiGateway
03:28:22PM DELETE_COMPLETE AWS::CloudFormation::Stack ApiGateway
03:28:41PM DELETE_COMPLETE AWS::CloudFormation::Stack JetsPreheatJob
03:28:42PM DELETE_IN_PROGRESS AWS::IAM::Role IamRole
03:28:42PM DELETE_IN_PROGRESS AWS::Lambda::LayerVersion GemLayer
03:28:43PM DELETE_COMPLETE AWS::IAM::Role IamRole
Stack jets-sandbox-dev deleted.
Time took for deletion: 1m 46s.
Deleting CloudWatch logs
Project jets-sandbox-dev deleted!

こちらで検証は以上です。お疲れ様でした!

終わりに

だいぶ長くなってしまいましたが、Jets を触ってみた所感としては、Rails のコンテキストを踏まえて簡単にアプリケーションを作成・デプロイできるので、割とすんなり動かせたなと思いました。

また、コマンドラインから AWS リソースをあまり意識せずにビルド・デプロイできるのも、習得コストが少なくていい感じです。

ただ、IAM の権限制御や実際のアプリケーションのパフォーマンスといった、本番環境で実運用するための考慮点はまだまだありそうなので、また別途検証をしてみようと思います!

参考URL

sonicgarden
「お客様に無駄遣いをさせない受託開発」と「習慣を変えるソフトウェアのサービス」に取り組んでいるソフトウェア企業
http://www.sonicgarden.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした