2019年1月29日火曜日

AWS lambda の Layers 機能を試す (Ruby 編)

概要

AWS lambda の layers は共有で使えるライブラリの機能です
関数で参照する共通処理をライブラリに登録しておくことでコードの記述量を減らすことができます
今回は Ruby を使った簡単な layers の使い方を紹介します

環境

  • AWS lambda 2019/01/25 時点
  • Ruby 2.5

簡単なレイヤー作成

まずはレイヤーを作成します
ローカルで準備します

  • mkdir -p ruby/lib/
  • touch ruby/lib/my_func.rb
  • vim ruby/lib/my_func.rb
def str_now
  Time.now.strftime("%Y/%m/%d %H:%M:%S")
end
  • zip -r my_ruby_gems.zip ./ruby/

ここで作成した zip をレイヤーとしてアップロードします

レイヤーを作成すると以下のようになります

アップロードできたら関数からレイヤーが参照できるようにレイヤーを追加します

レイヤーを使う関数を準備

あとは lambda に普通に関数を記述しましょう
今回レイヤーをデプロイしたパスは ruby/lib/ になります
この配下は lambda 上ですでに RUBY_LIB に登録されているのでファイル名だけで require することができます (フルパスで参照しなくて OK)

require 'json'
require 'my_func'

def lambda_handler(event:, context:)
    p str_now
end

テスト

あとはイベントを作成して実行してみましょう
以下のようにレイヤーに登録したライブラリを参照することができると思います

gem を使ったレイヤーを作成

lambda 上の関数で gem を使う場合に SAM を使った方法を紹介しました
その方法ではなくレイヤーに使いたい gem を登録することで lambda から gem を参照することもできます

まずローカルで準備します

  • mkdir -p ruby
  • bundle init
  • vim Gemfile
gem "aws-sdk"
  • bundle install --path=.

これで ruby/2.5.0/gems 配下に gem が配置されます
あとはこれを zip にして再度レイヤーとして登録します

  • zip -r my_ruby_gems.zip ./ruby/

今回は同じレイヤーにバージョン2 として登録しました
別のレイヤーとして登録しても OK です

バージョン2 のレイヤーを関数から参照しましょう
(同一レイヤーの別バージョンは参照できないかもしれません、、、エラーになる場合は最新のバージョンだけ参照するようにしてください、もしくは別レイヤーを作成して参照してください)

GEM_PATH の修正

lambda のデフォルトだと gem は /opt/ruby/gems/2.5.0 のパスを参照しています
今回は /opt/ruby/2.5.0 なのでこれを追加します

関数修正

今回はテストなのでとりあえず gem が参照できるかだけ確認します

require 'json'

def lambda_handler(event:, context:)
    p require 'aws-sdk'
end

テスト

イベントを適当に作成して実行しましょう
true になれば OK です

Tips

デフォルトだと lambda の実行時間は 3 秒以内でなければなりません
もしタイムアウトでエラーになる場合は設定を変更できるので少し伸ばしてあげましょう

最後に

lambda の Layers 機能を Ruby で試してみました
基本はライブラリ化したコードを zip にして lambda にアップロードすれば OK です

GEM_PATH を上書きして自分で追加した gem を lambda 上で参照する方法も紹介しました
gem を参照した共通ライブラリを作成する場合は gem は GEM_PATH に配置してそこを参照するライブラリを ruby/lib に配置する感じがベストプラクティスかなと思います
ローカルの環境と lambda 上の環境を合わせるのが少し大変そうですが bundler や rake を使ってうまくタスク化すれば何とかなると思います

参考サイト

1 件のコメント:

  1. わかりやすくてとても助かりました!
    ありがとうございます。

    返信削除