Ruby で Rails ライクにサーバーレスアプリケーションが作れる Jets を使ってみた
西田@大阪です
Rubyが好き人はいろいろなORMを使っていると、どうしてもActiveRecord が使いたくなる人もいるのではないでしょうか? 今回はRuby でサーバーレスアプリケーションが Railsライクで構築できる Jets を試してみました
試した環境
- jets: 2.3.12
jestsは2.3.12時点では ruby 2.5.3 を要求するため、事前にインストールしておきます
$ rbenv install 2.5.3 $ rbenv global 2.5.3
※ rbenv でのインストールコマンドです。試される場合はご自身の環境に合わせたコマンドでお使いください
Quick Start - Jets Ruby Serverless Framework に従い動かしてみたいと思います
インストール
Jetsをgemでインストールします
$ gem install jets
プロジェクトの作成
プロジェクトを作成します
$ jets new demo # postgresqlを使用する場合は以下 $ jets new demo --database=postgresql
以下のファイルが生成されます
. ├── Gemfile ├── Gemfile.lock ├── Procfile ├── README.md ├── Rakefile ├── app │ ├── controllers │ │ └── application_controller.rb │ ├── helpers │ │ └── application_helper.rb │ ├── javascript │ │ ├── packs │ │ │ ├── application.js │ │ │ └── theme.scss │ │ └── src │ │ └── jets │ │ └── crud.js │ ├── jobs │ │ └── application_job.rb │ ├── models │ │ ├── application_item.rb │ │ └── application_record.rb │ └── views │ └── layouts │ └── application.html.erb ├── bin │ ├── webpack │ └── webpack-dev-server ├── config │ ├── application.rb │ ├── database.yml │ ├── dynamodb.yml │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── routes.rb │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── production.js │ │ ├── staging.js │ │ └── test.js │ └── webpacker.yml ├── config.ru ├── db ├── package.json ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── favicon.ico │ └── index.html ├── spec │ ├── controllers │ │ └── posts_controller_spec.rb │ ├── fixtures │ │ └── payloads │ │ ├── posts-index.json │ │ └── posts-show.json │ └── spec_helper.rb └── yarn.lock
ライブラリ管理のための Gemfile
やコントローラーやテストのための spec
ファイルなどが出力されています。Railsでおなじみのファイルですね。
馴染みがない dynamodb.yml
やyarn.lock
も出力されています。(最近追えてないので最新の Rails では yarn が使われているのかもしれませんが)。
CRUDの雛形を作成
みんな大好き Scaffold です。Rails ライクに雛形を作成することができます
$ jets generate scaffold post title:string invoke active_record create db/migrate/20200125133928_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
データベースのスキーマ管理をするマイグレーションファイルやモデルとコントローラー、erbのテンプレート等が生成されています
データベースの接続先を変更する場合は .env.develoment
、.env.test
を編集します。
以下は127.0.0.1(localhost)の13306ポートでLISTENしているMySQLに接続するサンプルです
.env.develoment
# Example .env.development, meant to be updated. ENV_DEVELOPMENT_KEY=example1 # DATABASE_URL=mysql2://dbuser:dbpass@dbhost/demo_development?pool=5 # ↓↓追記部分 DATABASE_URL=mysql2://root@127.0.0.1:13306/demo_development?pool=5
.env.test
# Example .env.test, meant to be updated. env_key1=env_value1 env_key2=env_value2 # ↓↓追記部分 DATABASE_URL=mysql2://root@127.0.0.1:13306/demo_test?pool=5
マイグレーションを実行
以下のコマンドでデータベースを作成し、マイグレーションファイルを実行し、データベースの準備を行います
$ jets db:create db:migrate
サーバーを起動
$ jets server => bundle exec rackup --port 8888 --host 127.0.0.1 Jets booting up in development mode! Puma starting in single mode... * Version 4.3.1 (ruby 2.6.5-p114), codename: Mysterious Traveller * Min threads: 0, max threads: 16 * Environment: development * Listening on tcp://127.0.0.1:8888 Use Ctrl-C to stop
出力された内容からサーバーがRackで起動されされ127.0.0.1(localhost)の 8888 をLISTENしてることがわかります
ブラウザで開いてみます
$ open http://localhost:8888/posts
シンプルな画面が表示されました 「New Post」 リンクをたどり新規登録をしてみます
登録できることを確認できました
AWS 環境にデプロイ
AWS環境にデプロイしていきます
RDSを使うので VPC Lamdbda を使った環境にデプロイしていきたいと思います
事前に以下のAWSリソースが作成されている想定です
- VPC
- RDS
- サブネット
※ Lambdaが属するサブネットからNatGatewyへのルートが設定されていないと Lambda がタイムアウトしてしまう点にご注意ください
※ サンプルのCloudFormationテンプレートをご参照ください https://gist.github.com/cm-nishida-masayuki/800c8f6355de4f5c3128ad59834b9bf0
AWS環境でのDBへの接続情報を設定
AWS環境にデプロイした際に接続するRDSへの接続状況の設定を行います
.env.development.remote
ENV_DEVELOPMENT_KEY=example1 DATABASE_URL=mysql2://user:password@yourrdsendpoint/demo_development?pool=5
SubnetとSecurity Groupの設定します
config/environments/development.rb
Jets.application.configure do # Example: # config.function.memory_size = 1536 # config.action_mailer.raise_delivery_errors = false # Docs: http://rubyonjets.com/docs/email-sending/ config.function.vpc_config = { security_group_ids: %w[sg-xxx], subnet_ids: %w[subnet-xxx] } end
マイグレーションを Lambda 上で実行するためのjobを追加します
jobs/command_job
class CommandJob < ApplicationJob def execute command = event['command'] || 'uptime' sh command end def create sh "jets db:create" end def migrate sh "jets db:migrate" end private def sh(command) puts "=> #{command}" puts `#{command}` end end
デプロイします
$ jets deploy ~~~~ 省略 Stack success status: UPDATE_COMPLETE Time took for stack deployment: 2m 25s. Prewarming application. API Gateway Endpoint: https://yourendpoint.execute-api.ap-northeast-1.amazonaws.com/dev/
このコマンドで以下を作成する CloudFormation テンプレートが作成され実行されます
- API Gateway
- Lambda
アップロードされた Lambda の中に ${アプリケーション名}-${環境}-command_job-create
と ${アプリケーション名}-${環境}-command_job-migrate
があるので create => migrateの順でマネジメントコンソール上で実行します
deployコマンド実行時に出力されるURLに posts
をつけてブラウザからアクセスすれば動作を確認できます
最後に
いかかでしたでしょうか?筆者もしばらく Ruby を触れておらず、まだ機能不足なところもありますが、Serverless アプリケーションを Rails ライクでお手軽に作れるので、機会があれば積極的に使っていきたいと思います。この記事が誰かの参考になれば幸いです
参考
tongueroo/jets-command-project: Shows how to run any command on AWS Lambda