AWS Lambda の Ruby サポート を受けてRubyのインストールからデプロイまでやってみたメモ

https://aws.amazon.com/jp/about-aws/whats-new/2018/11/aws-lambda-supports-ruby/

ついに（やっと）AWS LambdaがRubyに対応したので、ローカル環境にRubyをインストールして、Lambdaファンクションを作ってテストまでやってみたメモです。

#Rubyのインストールと環境のセットアップ
セットアップする環境は次の通り。

- MacBook Pro
- macOS 10.13.6 (17G65)
- Darwin 17.7.0

##Ruby2.5をインストールする（ローカル環境のセットアップ）

LambdaでサポートされるRubyは2.5なので、まずRuby2.5をインストールする準備をします。
順番は次の通り。

- [Homebrew](https://brew.sh/)をインストール
- Homebrewから[rbenv](https://github.com/rbenv/rbenv)をインストール
- rbenvからRuby2.5をインストール

Ruby2.5.0をインストール
`rbenv install 2.5.0`

Ruby2.5.0を標準に設定
`rbenv global 2.5.0`
プロジェクトで切り替える時はこちら
`rbenv local 2.5.0`
確認
`rbenv versions`
`ruby -v`

#目標
目標としては、kintoneからLambdaにアクセスしてレスポンスを受けるまでをテストしますが、
今回は前段階としてkintoneは抜きにして、Rubyの環境設定からLambda関数のテストまでをやって見ます。

目標とする内容

1. kintoneにボタンを設定
2. ボタン押下でkintone.proxy経由でAWS APIGatewayにリクエストを投げる
3. Lambdaで受けて
4. 何か処理して
5. 処理結果をkintoneに返す

今回の内容
1. ローカルにRubyのセットアップ
2. LambdaにRubyスクリプトをアップロード
3. テスト実行
4. 確認

#RubyにPDF生成ライブラリ(thinreports)をインストール

Rubyで何かやるのにライブラリのインストールは必要となるので、ローカル環境にライブラリをインストールして、それをパッケージングした後にLambdaにデプロイする方法をトライをしてみます。

##RubyのGemライブラリをインストールする流れ
1. gem install bundler で [Bundler](https://bundler.io/)をインストール
2. bundle init して設定ファイルのテンプレートを作成
3. Gemfile にインストールするライブラリを追加
4. bundle install --path vendor/bundle --pathオプションをつけることで、ライブラリのインストールパスをデプロイ対象のディレクトリのパスに含めるようにします。

```bash
$ gem install bundler
Fetching: bundler-1.17.2.gem (100%)
Successfully installed bundler-1.17.2
$ bundler -v
Bundler version 1.17.2
$ bundle init
$ ls -la
total 136
drwxr-xr-x  5 kazoo  staff    160 12 22 17:06 .
drwxr-xr-x  4 kazoo  staff    128 12 21 20:23 ..
-rw-r--r--  1 kazoo  staff    146 12 22 17:06 Gemfile
-rwxr-xr-x@ 1 kazoo  staff    715  4 24  2015 hello_world.rb
-rwxr-xr-x@ 1 kazoo  staff  60365  4 24  2015 hello_world.tlf
$ vi Gemfile
$ cat Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "thinreports"
$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/...............
Resolving dependencies...
Using bundler 1.17.2
Fetching pdf-core 0.7.0
Installing pdf-core 0.7.0
Fetching ttfunk 1.5.1
Installing ttfunk 1.5.1
Fetching prawn 2.2.2
Installing prawn 2.2.2
Fetching thinreports 0.10.3
Installing thinreports 0.10.3
Bundle complete! 1 Gemfile dependency, 5 gems now installed.
Bundled gems are installed into `./vendor/bundle`
$ cat Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    pdf-core (0.7.0)
    prawn (2.2.2)
      pdf-core (~> 0.7.0)
      ttfunk (~> 1.5)
    thinreports (0.10.3)
      prawn (~> 2.2.0)
    ttfunk (1.5.1)

PLATFORMS
  ruby

DEPENDENCIES
  thinreports

BUNDLED WITH
   1.17.2
```
#パッケージングしてLambdaにデプロイする
Rubyスクリプトとライブラリをzipコマンドでパッケージし、パッケージしたzipファイルをAWSコンソールからアップロードします。
1. zip -r hello_world.zip hello_world.rb hello_world.tlf vendor/
2. S3バケットを作成。（Lambdaからアクセスが出来れば良いです）
3. S3にzipファイルをアップロードします。（設定は全てデフォルトで良いです）
4. S3にアップロードされたzipファイルを選択してオブジェクト URLをコピーしておきます。
5. AWSコンソールにログイン。Lambdaサービスから関数の作成を選択します。
6. ランタイムはRuby2.5を選択
7. コードエントリタイプにてS3にアップロードしたzipファイルを選択します。
8. zipファイルのURLをセットして保存を押下します。
9. ハンドラはアップロードしたメインスクリプトのファイル名を指定します。(ファイルがhello_world.rbでメソッド名がlambda_handlerの時は、hello_world.lambda_handlerとします）
10. テストを作成して、実行し成功することを確認します。

```bash
$ ls -la
total 81592
drwxr-xr-x  9 admin  staff       288 12 23 13:08 .
drwxr-xr-x  4 admin  staff       128 12 21 20:23 ..
drwxr-xr-x  3 admin  staff        96 12 22 17:16 .bundle
-rw-r--r--  1 admin  staff       165 12 22 17:07 Gemfile
-rw-r--r--  1 admin  staff       269 12 22 17:16 Gemfile.lock
-rwxr-xr-x@ 1 admin  staff       947 12 23 13:04 hello_world.rb
-rwxr-xr-x@ 1 admin  staff     60365  4 24  2015 hello_world.tlf
-rw-r--r--  1 admin  staff  41677022 12 23 13:08 hello_world.zip
drwxr-xr-x  3 admin  staff        96 12 22 17:16 vendor
$ zip -r hello_world.zip hello_world.rb hello_world.tlf vendor/
```
```hello_world.rb
# coding: utf-8
require 'thinreports'
require 'json'

report = Thinreports::Report.new layout: 'hello_world'
def lambda_handler(event:, context:)
    # TODO implement
    { statusCode: 200, body: JSON.generate('Hello from Lambda. powerd by Ruby!!') }
end

```

#API Gatewayの設定
外部から接続する為、今回はAPI Gatewayを利用します。

1. Lambda関数画面のトリガーの追加一覧からAPI Gatewayを選択します。
2. 生成されたAPI エンドポイントにアクセスしてLambda関数から実行したRubyスクリプトの実行結果が表示されることを確認します。

#まとめ
今回は、Rubyスクリプトをライブラリを含んでLambdaにアップロードして、API Gateway経由で接続し、テストまで実施して見ました。
次回はkintoneから接続してLambdaでPDFを生成し、表示したいと思います。

#お世話になりました

- [rbenvをupdateして最新のRubyバージョンをインストール](https://morizyun.github.io/ruby/rbenv-update-mac-homebrew.html)
- [Homebrew使い方まとめ](https://qiita.com/vintersnow/items/fca0be79cdc28bd2f5e4)
- [AWS Lambda Ruby Runtimeを使ってサーバーレスなSinatraアプリケーションを作る #reinvent](https://dev.classmethod.jp/cloud/aws/serverless-sinatra/)
- [外部APIの実行](https://developer.cybozu.io/hc/ja/articles/202166320)
- [kintoneマッシュアップのための豆知識（curlコマンドとkintone.proxy()の対応）](https://developer.cybozu.io/hc/ja/articles/203446970?flash_digest=df603d25164049b822968c835d1f32566218f52b)
- [【mac】zipファイル操作コマンド](https://qiita.com/griffin3104/items/948e38aab62bbb0d0610)
- [Lambda + API Gateway入門。Rest API作成](http://xp-cloud.jp/blog/2018/07/17/3657/)