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

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


はじめに

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

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)