Ruby + AWS Lambdaを使ってみて思った注意点

仕事の関係でLambdaで定期実行するプログラムを書くことになった。 前のバイトでLambda自体は触ったことがあったが、そのときはnodeで書いた上そんなに複雑なことはしなかったので困ったことがあってもググれば問題なかった。 ただ、今回少し複雑な処理を行うため自分の得意言語を使いたくてRubyを選択したが意外と苦戦するシーンが有ったのでその紹介。

ライブラリを使うときが少し面倒

rubyで各種ライブラリを使うときは、ローカルで
bundle install --path .bundle
みたいな感じでインストールを実行し、
bundle exec ruby xxx.rb
でファイルを実行していたと思う。 ただ、Lambdaではこの「bundle install」をLambda上で行うことができないので前もってローカルでbundle installしたファイルをアップロードする必要がある。

手順

  1. zip -r lambda.zip *
  2. Lambda上で「.zipファイルをアップロード」を選択
  3. アップロード
※基本的にライブラリはそれなりに容量があるのでインラインコード編集は使えません

ローカルとLambdaでの環境切り替え

これはLambda + Rubyに限ったことではないが、Lambdaではデフォルトで「lambda_function.rbファイルのlambda_handlerメソッド」が呼ばれる様になっているが、ローカル環境ではもちろんそんな設定はない。 そのため、自分はLambdaの方に環境変数を設定して、分けることにした
if ENV['ENV'] == 'lambda'
    //Lambdaのときの処理
else
    //ローカルのときはlambda_handlerを呼び出す
    lambda_handler(event:'',context:'')
end
上記のようにすればローカル環境のときはlambda_handlerを呼び出して、Lambdaのときは繰り返し呼ばれないようにできる。

普通では使えないライブラリがある

少し前にライブラリの使い方について説明したがいくつかのライブラリはあれだけでは使えない。 具体的には「Nokogiri」が使うことができなかった。 理由としては、NokogiriがC拡張を使っているとかそーゆー理由だった気がします。 とにかく、普通の自分の環境でbundle installではだめである。 そこで、 https://github.com/masarakki/aws-lambda-ruby これを使います。 このリポジトリをクローンして、そのディレクトリに入り、自分のGemfileをおいて
docker run -it -v `pwd`:`pwd` -w `pwd` -u `id -u`:`id -g` masarakki/aws-lambda-ruby bundle install --path vendor/bundle
こんな感じでDockerを介したbundle installをしてできたファイルをzip化してあげる必要があります。

タイムアウトエラー連発

よっしゃ!!できたぞ!! と思って実行したらタイムアウトエラーで怒られてしまう... ローカルで動かしてたときは30秒もかからないのに... 原因は「初回起動時はbundleを読み込むのに時間がかかる」ことでした。 そのため、ローカルで起動するより非常に遅いです!! 自分の場合ローカルでは1分もかからないですけど、5分くらいに設定してます... 自分が詰まった4つの点をまとめてみましたー