AWS Lambda で Rubyを使う(Hello worldからDynamoDBとの連携まで)

AWS Lambda で Rubyを使う(Hello worldからDynamoDBとの連携まで):


Ruby support for Lambda

LambdaでついにRuby Runtimeがサポートされました。



UNADJUSTEDNONRAW_thumb_34b8.jpg


現在対応しているバージョンは2.5です。

とにかく触ってみることが大事ということで、早速動かしてみました。

  • Hello world
  • DynamoDB連携
  • pythonとnodeとの速度比較


Lambda関数を作成

もうGAなので選択肢にruby2.5が表示されています。(嬉しい...!)


screenshot1.png


作成。


スクリーンショット 2018-11-30 4.37.47.png


最初のコードはこんな感じですね。

lambda_function
require 'json' 
 
def lambda_handler(event:, context:) 
    # TODO implement 
    { statusCode: 200, body: JSON.generate('Hello from Lambda!') } 
end 
何はともあれとりあえずこのまま実行します。 Hello from Lambda!



screenshot2.png



色々遊んで見る

標準ライブラリ以外を利用したい場合には、NodeやPyrhonなどと同じように、ローカルでrubyアプリを作成してそれをまとめてsamでアップロードする形になります。 AWSブログのチュートリアルを使って解説していきます。


DynamoDBとの連携


1. 下準備
まずはローカルにアプリディレクトリを作ります。

bash
$ mkdir lambda_ruby 
$ cd lambda_ruby 

2. Gemfileを作成する
中身にaws用のライブラリを記述します。他のライブラリを利用したい場合は合わせて書くと良いでしょう。

Gemfile
source 'https://rubygems.org' 
gem 'aws-record', '~> 2' 
bundle installも忘れずに実行してください。ローカルのrubyにインストールしたい場合はbundle installだけでもいいのですが、今回はライブラリも含めてLambda側にdeployするので、--deploymentオプションを付けて実行しておきましょう

bash
$ bundle install --deployment 

3. Lambdaの実行スクリプトを作成する
hello_ruby_record.rbを作成します。 put_item を今回のlambdaのhandlerメソッドとしています。(後述のtemplate.yamlの設定でhandlerの関数は自由に指定できます)

hello_ruby_record.rb
require 'aws-record' 
 
class DemoTable 
  include Aws::Record 
  set_table_name ENV[‘DDB_TABLE’] 
  string_attr :id, hash_key: true 
  string_attr :body 
end   
 
def put_item(event:,context:) 
  body = event["body"] 
  item = DemoTable.new(id: SecureRandom.uuid, body: body) 
  item.save! # raise an exception if save fails 
  item.to_h   
end 

4. template.yamlの作成
lambda側にアップロードするための設定ファイルを作成します。Lambda側へのアップロードは、AWS SAM を利用します。

template.yaml
AWSTemplateFormatVersion: '2010-09-09' 
Transform: AWS::Serverless-2016-10-31 
Description: 'sample ruby application' 
 
Resources: 
  HelloRubyRecordFunction: 
    Type: AWS::Serverless::Function 
    Properties: 
      Handler: hello_ruby_record.put_item 
      Runtime: ruby2.5 
      Policies: 
      - DynamoDBCrudPolicy: 
          TableName: !Ref RubyExampleDDBTable  
      Environment: 
        Variables: 
          DDB_TABLE: !Ref RubyExampleDDBTable 
 
  RubyExampleDDBTable: 
    Type: AWS::Serverless::SimpleTable 
    Properties: 
      PrimaryKey: 
        Name: id 
        Type: String 
 
Outputs: 
  HelloRubyRecordFunction: 
    Description: Hello Ruby Record Lambda Function ARN 
    Value: 
      Fn::GetAtt: 
      - HelloRubyRecordFunction 
      - Arn 
今回はLambda関数とDynamoDBテーブルを利用するので、Serverless::FunctionとServerless::SimpleTableをリソースとして定義します。

このテンプレートファイルの詳しい解説はチュートリアルを見てください。


5. 一旦フォルダ構成を確認
今までの作業でフォルダ内はこの様になっているはずです。

$ tree -L 2 -a 
 . 
 ├── .bundle 
 │   └── config 
 ├── Gemfile 
 ├── Gemfile.lock 
 ├── hello_ruby_record.rb 
 └── vendor 
 └── bundle 
あとはSAMを使ってdeployを実施するだけです。


6. SAMパッケージの作成
SAMが入っていない場合はインストールしておきます。

$ pip install aws-sam-cli 
先程作成したテンプレートファイルを使ってsamパッケージを作成します。

※S3バケットは予め作成しておいてください。

sam package --template-file template.yaml \ 
 --output-template-file packaged-template.yaml \ 
 --s3-bucket <bucketname> 
フォルダにpackaged-template.yamlが作成されたら成功です。


7. パッケージのアップロード
SAMのdeployコマンドを利用してパッケージをアップロードします。
stack-nameはlambdaの関数名になりますので、好きな名前を入力してください。

$ sam deploy --template-file packaged-template.yaml \ 
 --stack-name helloRubyDynamo \ 
 --capabilities CAPABILITY_IAM 
 
 Waiting for changeset to be created... 
 Waiting for stack create/update to complete 
 Successfully created/updated stack - helloRubyRecord 
注意点

CLIに紐付いているIAMにCloudFormationの権限を付けておかないとエラーになります。

An error occurred (AccessDenied) when calling the CreateChangeSet operation:  
 User: arn:aws:iam::*** is not authorized to perform:  
 cloudformation:CreateChangeSet on resource: 
 arn:aws:cloudformation:ap-northeast-1:***:stack/helloRubyDynamo/* 

8. テスト
CloudFormationでデプロイしたので、DynamoDBのセットアップも含めてデプロイが完了しています。下記のようなテストイベントを送ってテストしてみましょう

テストイベントの設定
{"body": "hello lambda"} 
成功しました。


screenshot3.png


DynamoDBにも同じ値が入っていますね。


スクリーンショット 2018-11-30 8.49.46.png


こんな感じです。途中からSAMの解説になってしまいましたが、Rubyのライブラリを入れたいならSAMを導入しておくとその後の手間が大いに削減されるので、設定しておいて損はないと思います。


処理時間はどうなのか計測

nodeやpythonと違い、新しく発表されたCustom Runtimeをバックエンドに利用しているとのことなので、ruby Runtimeの読み込み時間なども含めて処理時間ってどうなんだろう、と気になったので、計測しました。


初回起動
言語 バージョン 実行時間
ruby 2.5 23.31 ms
node.js 8.10 12.28 ms
python 3.7 4.62 ms
なるほど。。。Custom Runtimeの読み込み分が乗っかってる感じでしょうかね。。。


2回目以降
それぞれ100回叩いて平均値を計測する予定。


終わりに

個人的にも馴染みのあるRubyがサポートされたのは非常に嬉しかったですね。

これからどんどん使っていきたいと思います。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2024-02-12 22:08:06 RSSフィード2024-02-12 22:00分まとめ(7件)