Jets触ってみた(ruby serverless)

# Jetsとは？
rubyをサーバーレスで動かせ、なおかつRailsライクにコードがかけるフレームワークです。
DBとしてRDBとDynamoDBの両方に対応されている。(今回はRDSと組み合わせました)
=> RDBはORマッパーとしてActiveRecordが採用されているので本当にRailsのようにかけました
https://rubyonjets.com/

# 背景
Railsは使い慣れているけどEC2なりFargateなどの料金を地味に取られ続ける。。
=> 個人開発ではなるべく金額下げたいなぁというお気持ち

Serverless Frameworkを利用してlambda x rubyを試してみる
=> lambdaとRDSの相性が悪いがDynamoよくわからん...(個人開発としてはこれも頑張って勉強したい :muscle: )

ちょっとした個人開発用にRailsをサーバーレスで動かせないかなぁ。。。。
そんな時に二つの記事に初めまして
[「Lambda-RDS」パターンももう怖くない！？フェイルオーバーももっと早くなるよ！ RDS Proxyがプレビュー公開されました！#reinvent](https://dev.classmethod.jp/articles/rds-proxy-reinvent2019/)
[Ruby で Rails ライクにサーバーレスアプリケーションが作れる Jets を使ってみた](https://dev.classmethod.jp/articles/ruby-jets-serverless/)

Jetsの実際の使い方に関しては想像以上にRailsライクなのでそこまでつまづかなかった&公式か上の記事で問題なかったのでそちらでお試しください :bow: 

--
サーバーレスに関して気になった最近の動向まとめましたのでこちらもどうぞ
[個人的に気になる最近のサーバーレス事情
](https://qiita.com/tatematsu-k/items/a23de719afad9af38117)

# 地味につまづいた小言
## ruby2.7に対応してなかった。。。rubyは2.5系で
最初2.7で作ろうとしていたのですがまだ2.7系にサポートしておらず2.5系に変える必要が...
issueにもなっているので様子を見ながら応援したいところ
https://github.com/boltops-tools/jets/issues/444

#### 追記
こちら無事にRuby2.7系がサポートされました :tada: 

## 毎回region聞かれる
jetsのコマンドを打つと毎回region聞かれる...w
AWS_PROFILEのdefaultに何か入れればきっと問題なく動くかと(私はAWS_PROFILEを毎回指定してました)
何か回避方法があるのかもしれないがサラッと見てわからなかったです

```rb
$ jets server
Traceback (most recent call last):
...

/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/aws-sdk-core-3.110.0/lib/aws-sdk-core/plugins/regional_endpoint.rb:42:in `block in <class:RegionalEndpoint>': Invalid `:region` option was provided. (Aws::Errors::InvalidRegionError)

* Not every service is available in every region.

* Never suffix region names with availability zones.
  Use "us-east-1", not "us-east-1a"

Known AWS regions include (not specific to this service):

af-south-1
ap-east-1
ap-northeast-1
...
```

## VPC内のRDSにアクセスするためlambdaにVPCを接続する
こちらの公式の通りにsubnetとsecurity_groupを指定することで解決
https://rubyonjets.com/docs/considerations/vpc/

```rb
Jets.application.configure do
  config.function.vpc_config = {
    security_group_ids: %w[sg-1 sg-2],
    subnet_ids: %w[subnet-1 subnet-2],
  }
end
```

## VPC内のRDSにマイグレーションが流せない...
これに対する銀の弾丸が見つけられず.....
公開されているRDSであれば `JETS_ENV_REMOTE=1 jets db:migrate` でローカルからapplyすることが可能
一つの方法として参考のリンクでApplicationJobを用意してそれを実行する方法が紹介されていました
ただし本番環境で行う場合、lambdaのタイムアウトがあるのでECS Fargateのタスクとかにしておいた方がいいのかも？
どちらにしても本番での運用の難しさがありそうです

参考)
https://community.rubyonjets.com/t/how-do-i-migrate-the-database/22

## RDS Proxyはどうやって設定する？
結論。不要そうです笑
> On AWS Lambda, there’s something called the Lambda Execution Context. The Lambda Execution Context gets reused between lambda function runs. Jets establishes the DB connection within the Lambda Execution Context outside the handler. So DB connections get reused between subsequent lambda function runs. This prevents DB connections from ever-increasing. The AWS docs specifically point out to use the Lambda Execution Context for things like establishing DB connections.

引用: https://rubyonjets.com/docs/database/activerecord/

lambdaにはLambda Execution Contextという実行間で共有のスペースがあるようで(初耳でした :see_no_evil: )、
Jets内部でLambda Execution Contextにコネクションを保持することで実行間でコネクションを使いまわしてくれるようです。

※ コネクションプールをアプリケーション(Jets)管理にするかAWSマネージド(RDS Proxy)にするかは別途検討してもいいかなと思います。

# 所管
- まだ本番で使うには時期尚早かなと思いました
- 今後ruby on lambdaを採用する上で一つの大きな選択肢になりそうという期待したい！
- まだドキュメントや記事が少ないのでつまづくとだいぶ時間がかかりました(特にVPC周りでわからずちょいちょい作り直しとかになってしまいました。。)