初めまして、Railsエンジニアの白井です。 最近彼女が出来て会社の人に幸せ(惚気)を振りまく活動をしています!
さて、先日AWS re:Invent 2018にてAWS LambdaがRubyランタイム対応の発表がなされました!(リリース)
弊社は私含めRubyエンジニアが多数いるため、とてもとても嬉しいアナウンスメントでした。
早速使ってみるとNative Extensionsを使用するgemを使いたい時にちょっと詰まったのでシェアします!
この記事を読んだらわかること
この記事では、 AWS Lambda RubyランタイムでNative Extensionsを使用するgemを使ったLambda関数を作る手順をまとめています。
※Native Extensionsを使用しないgemのみを使ったLambda関数は未検証です。
※serverelessを使用して簡易的に行なっていますが、使用しない場合は置き換えて読んでください。
Native Extensionsを使用するgemをLambdaで使うには
Native Extensionsを用いたgemを使いたい場合はLambda 実行環境と 同等の環境 でbundle install、デプロイしてあげる必要があります。
幸いにもLambdaのベースとなるAMI(ログインが必要です)が公開されているのでここにRubyとserverlessの環境を作り、デプロイしてみましょう。
Lambdaが動作している環境と同じ環境を作る
AMI - amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2(ログインが必要です)にアクセスするとLambdaのベースとなるAMIがあります。 「作成」 から指示に従ってEC2インスタンスを作成します。インスタンスタイプはt2.microの無料枠で済ませてしまいましょう!
インスタンスが立ち上がったらsshしてRubyとServerlessをインストールします。
# ※この記事ではセットアップの詳細の説明は省かせていただきます。 # 必要なパッケージのインストール sudo yum -y install gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel libffi-devel libxml2 libxslt libxml2-devel libxslt-devel sqlite-devel git nodejs make # rbenvのインストール git clone https://github.com/sstephenson/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile echo 'eval "$(rbenv init -)"' >> ~/.bash_profile source ~/.bash_profile git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build sudo ~/.rbenv/plugins/ruby-build/install.sh # rubyのインストール rbenv install 2.5.3 rbenv global 2.5.3 # bundlerのインストール gem install bundler # nodejs, npm, serverlessのインストール curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash - sudo npm install -g serverless echo 'export AWS_ACCESS_KEY_ID={YOUR_AWS_ACCESS_KEY_ID}' >> ~/.bash_profile echo 'export AWS_SECRET_ACCESS_KEY={YOUR_AWS_SECRET_ACCESS_KEY}' >> ~/.bash_profile source ~/.bash_profile
これで準備が整いました!
実際に簡単なRuby Lambda関数を作ってみる
作るもの
お世話になっている方も多いであろうgem fakerを使わせていただき、実行するたびにFakeな名前を生成してくれる関数を作ってみます。
serverlessのテンプレートからプロジェクトを開始
serverless create --template aws-ruby --path faker cd faker bundle init
すると
. ├── Gemfile ├── handler.rb └── serverless.yml
が生成されますね。
早速fakerを追加してbundle installしましょう。
# Gemfile # frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem 'faker', :github => 'stympy/faker', :branch => 'master'
# Gemfile.lockの更新 bundle install # Gemfile.lockを読み込んで vendor/bundle に依存gemをインストール bundle install --deployment
次は関数ですね。
# handler.rb require 'rubygems' require 'bundler' Bundler.require def hello(event:, context:) prefix = event['prefix'] { statusCode: 200, body: JSON.generate(prefix + Faker::Name.name) } end
非常にシンプル!笑
デプロイ・実行
ではデプロイして実行してみましょう。
serverless deploy
次にデプロイしたlambda関数を実際に実行してみましょう。
# input_event.json { "prefix": "Mr." }
serverless invoke -f hello -p input_event.json # => { # "statusCode": 200, # "body": "Mr.Ginger Lockman" # }
できた!
ジンジャーロックマンってだれ。
裏話
実はもともと複数のRubyプロジェクトで使う予定で不動産投資シミュレーションの社内プライベートgemを開発していたのですが、途中で他言語でも使いたいニーズが出てきて、traveling-rubyで無理くりrubyを動かしてAPI化したその次の日にLambda Rubyサポート発表があってびっくり!
traveling-rubyはRuby 2.2.2までしか対応していないのでわざわざgemを古い記法に書き直したりもしていたのですが、そんな苦労があと1日待てば必要なかったという笑
とはいえ、とても素晴らしい発表でした! Rubyエンジニアが多い弊社でもLambdaを扱える人が増えてありがたい限り!
また新しい発見があったらブログ書きますね!