日本で 128 番目くらいに Ruby で AWS Lambda を試したメモ
日本で 128 番目くらいに Ruby で AWS Lambda を試したメモ:
ずっと待たれていたはず, もはや諦めかけていたかもしれない AWS Lambda のランタイムに Ruby が追加されたとの一報が我々の元に入りました.
https://aws.amazon.com/jp/blogs/compute/announcing-ruby-support-for-aws-lambda/
おお〜. なんちゃって Rubist の私もこれまで作ってきた Ruby スクリプトを Lambda で実行出来るかもしれないという興奮が今も続いております.
早速, 上記の URL に掲載されているサンプルを参考に簡単な Ruby スクリプトを Lambda 上で動かしてみたいと思います.
以下のような環境で動作確認を取ります.
初めて sam を使ってみましたが, とても簡単に Lambda ファンクションのデプロイまで出来ました. Serverless framework と比較すると機能不足は否めませんが, AWS 純正なので新サービスへの対応も早かったりするのかなということで, もう少し使い込んでみようと思います.
とりあえず, ローカルで Ruby で書いた関数を動かしてみたいので, Lambda をローカルで実行する際に利用するサンプルイベントを生成します.
これを実行すると, 以下のような JSON イベントが生成されます.
今回は, この JSON イベントから S3 のオブジェクトキーを抜き出す関数を Ruby で書いてみます.
す, すいません. とりあえず, 雑に書きました.
なんのひねりも, エラー処理もない, 自分の Ruby スキルのレベルが伺えるスクリプトです.
template.yaml (.yml ではない) を以下のように書きました.
なんとなく CloudFormation のテンプレートっぽい佇まいです.
sam にもローカルで Lambda ファンクションを実行出来る
引き続き, デプロイです. sam では CloudFormation のテンプレートを書き出して, そのテンプレートを使って Create Stack するような感じでデプロイするようです. もしかしたら, Serverless Framework も同じような挙動なのかもしれません. 以下のように 2 ステップでデプロイしました.
以下のように出力されました.
動作確認も Ruby で書きましょう. 以下のように aws-sdk-lambda を使ったコードです. 事前に aws-sdk-lambda をインストールしておきましょう.
以下のように出力されました.
おお〜, いい感じです. CloudWatch Logs にもログが記録されていることを確認しています.
Ruby で Lambda ファンクションが書けるなんて, 今年の頭に誰が予想していたでしょうか (結構, 予想していたりしたらすいません). 本当に嬉しい限りです.
レッツ Ruby on Lambda〜〜.
加藤さん, 事件です.
ずっと待たれていたはず, もはや諦めかけていたかもしれない AWS Lambda のランタイムに Ruby が追加されたとの一報が我々の元に入りました.https://aws.amazon.com/jp/blogs/compute/announcing-ruby-support-for-aws-lambda/
おお〜. なんちゃって Rubist の私もこれまで作ってきた Ruby スクリプトを Lambda で実行出来るかもしれないという興奮が今も続いております.
ということで
早速, 上記の URL に掲載されているサンプルを参考に簡単な Ruby スクリプトを Lambda 上で動かしてみたいと思います.
検証環境
以下のような環境で動作確認を取ります.$ ruby --version ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17] $ python --version Python 3.7.0 $ sam --version SAM CLI, version 0.8.0 $ aws --version aws-cli/1.16.66 Python/3.7.0 Darwin/17.7.0 botocore/1.12.56
まずは, サンプルイベントを生成する
とりあえず, ローカルで Ruby で書いた関数を動かしてみたいので, Lambda をローカルで実行する際に利用するサンプルイベントを生成します.$ sam local generate-event s3 put --bucket=foo --key=bar > event_file.json
$ cat event_file.json { "Records": [ { "eventVersion": "2.0", "eventSource": "aws:s3", "awsRegion": "us-east-1", "eventTime": "1970-01-01T00:00:00.000Z", "eventName": "ObjectCreated:Put", "userIdentity": { "principalId": "EXAMPLE" }, "requestParameters": { "sourceIPAddress": "127.0.0.1" }, "responseElements": { "x-amz-request-id": "EXAMPLE123456789", "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH" }, "s3": { "s3SchemaVersion": "1.0", "configurationId": "testConfigRule", "bucket": { "name": "foo", "ownerIdentity": { "principalId": "EXAMPLE" }, "arn": "arn:aws:s3:::foo" }, "object": { "key": "bar", "size": 1024, "eTag": "0123456789abcdef0123456789abcdef", "sequencer": "0A1B2C3D4E5F678901" } } } ] }
祝・Ruby で書く Lambda ファンクション
す, すいません. とりあえず, 雑に書きました.def hello(event:, context:) key = event["Records"][0]["s3"]["object"]["key"] key end
sam に必要な template.yaml
template.yaml (.yml ではない) を以下のように書きました.AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: 'serverless ruby sample.' Resources: ServerlessRubySample: Type: AWS::Serverless::Function Properties: Handler: sample.hello Runtime: ruby2.5 Outputs: ServerlessRubySample: Description: Serverless Ruby Sample Lambda Function ARN Value: Fn::GetAtt: - ServerlessRubySample - Arn
Runtime
の ruby2.5
が眩しいです.
まずはローカルでテスト
sam にもローカルで Lambda ファンクションを実行出来る local invoke
というサブコマンドが用意されていますので, これを利用することで簡単にローカルで実行することが可能です.$ sam local invoke ServerlessRubySample -e event_file.json 2018-11-30 08:33:13 Found credentials in shared credentials file: ~/.aws/credentials 2018-11-30 08:33:14 Invoking sample.hello (ruby2.5) Fetching lambci/lambda:ruby2.5 Docker container image...... 2018-11-30 08:33:17 Mounting /path/to/serverless-ruby-sample as /var/task:ro inside runtime container START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: $LATEST END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Duration: 5.64 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB "bar"
"bar"
が出力されることを確認出来ます. あっという間にローカル環境で Ruby で書いた Lambda ファンクションが動いてしまいました.
あとはデプロイ
引き続き, デプロイです. sam では CloudFormation のテンプレートを書き出して, そのテンプレートを使って Create Stack するような感じでデプロイするようです. もしかしたら, Serverless Framework も同じような挙動なのかもしれません. 以下のように 2 ステップでデプロイしました.# packaged-template.yaml を生成 sam package --template-file template.yaml \ --output-template-file packaged-template.yaml \ --s3-bucket oreno-sam-bucket # packaged-template.yaml を利用してデプロイ sam deploy --template-file packaged-template.yaml \ --stack-name ServerlessRubySample \ --capabilities CAPABILITY_IAM
# packaged-template.yaml を生成 $ sam package --template-file template.yaml \ > --output-template-file packaged-template.yaml \ > --s3-bucket oreno-sam-bucket Uploading to b55e36e493168dc4d6627ee148c1ac97 1275 / 1275.0 (100.00%) Successfully packaged artifacts and wrote output template to file packaged-template.yaml. Execute the following command to deploy the packaged template aws cloudformation deploy --template-file /Users/kawahara/sandboxies/sam/serverless-ruby-sample/packaged-template.yaml --stack-name <YOUR STACK NAME> # packaged-template.yaml を使って Create Stack しているのかな... $ sam deploy --template-file packaged-template.yaml \ > --stack-name ServerlessRubySample \ --capabilities CAPABILITY_IAM> --capabilities CAPABILITY_IAM Waiting for changeset to be created.. Waiting for stack create/update to complete Successfully created/updated stack - ServerlessRubySample
動作確認
動作確認も Ruby で書きましょう. 以下のように aws-sdk-lambda を使ったコードです. 事前に aws-sdk-lambda をインストールしておきましょう.require 'aws-sdk-lambda' require 'json' client = Aws::Lambda::Client.new(region: 'ap-northeast-1') payload =<<"EOS" { "Records": [ { "s3": { "s3SchemaVersion": "1.0", "configurationId": "testConfigRule", "bucket": { "name": "foo", "ownerIdentity": { "principalId": "EXAMPLE" }, "arn": "arn:aws:s3:::foo" }, "object": { "key": "bar", "size": 1024, "eTag": "0123456789abcdef0123456789abcdef", "sequencer": "0A1B2C3D4E5F678901" } } } ] } EOS resp = client.invoke({ function_name: 'ServerlessRubySample-ServerlessRubySample-xxxxxxxxxxx', invocation_type: 'RequestResponse', log_type: 'None', payload: payload }) res = JSON.parse(resp.payload.string) puts res
function_name
だけは, マネジメントコンソールで確認しましょう. このスクリプトを適当に invoke.rb とか名前をつけて保存しておきます.$ bundle exec ruby invoke.rb
$ bundle exe ruby invoke.rb bar
以上
Ruby で Lambda ファンクションが書けるなんて, 今年の頭に誰が予想していたでしょうか (結構, 予想していたりしたらすいません). 本当に嬉しい限りです.レッツ Ruby on Lambda〜〜.
コメント
コメントを投稿