AWS LambdaはS3やKinesis、DynamoDBのイベントをトリガーにJavaScript/Node.jsで書かれたコードスニペットを実行するというサービスです。
イベントの実行元として上記以外にAPIからの直接実行も可能となっているので今回はAWS SDK for Rubyを利用してこれを試してみます。
なお、AWS Lambdaをサポートしているのはv2だけとなります。
実際のところ、Rubyアプリケーションから実行することはないと思います。
なぜならRubyのアプリを動かすということは恐らくEC2なり何らかのサーバ上で実行してると思われるからです。
でも、例えばクライアントサイドとしてRubyを使うツールを用意して少しだけサーバサイドで処理したいっていうときにEC2とか立てる必要がないのは嬉しいかも知れません。
そんなシチュエーションあるかはわかりませんが。
というわけで早速やってみます。
今回はシンプルに登録済みのLambda functionをRubyのコードから実行するだけにしますが、Lambda functionの作成から実行するコードのアップロードもRubyで実行することが可能です。
とりあえずGemfileはこんな感じにします。
source "https://rubygems.org"
gem 'aws-sdk', '2.0.10.pre'
まず、Lambda functionとして登録するコードを以下のように用意します。今回はシンプルに実行時に渡されるパラメータの値を読み取ってログ出力するだけです。
exports.handler = function(event, context) {
console.log('value1 = ' + event.key1);
context.done(null, 'Invoke from Ruby');
};
新たにLambda functionを作成してこのコードを登録しておいてください。
今回はとりあえずのお試しなのでその他のパラメータはデフォルトで構いません。また、今回はSDKからの実行ですのでEvent Sourceの指定は行いません。
名前は適当につけます。例ではinvoke-from-rubyという名前にしました。
さて、次に作成したLambda functionを起動するRuby側のコードを用意します。
require 'aws-sdk'
Aws.config[:region] = "us-east-1"
lambda = Aws::Lambda::Client.new
begin
param = { key1: "from ruby"}.to_json #=>functionに渡すパラメータをJSON形式で作成
resp = lambda.invoke_async(function_name: "invoke-from-ruby", invoke_args: param)
if resp[:status] == 202
puts "success"
end
rescue Aws::Lambda::Errors::ServiceError => e
p e.message
end
これだけです。
functionに渡すパラメータはJSON形式で用意します。ここで指定したJSON形式のパラメータがfunction側ではeventとしてJavaScriptのmoduleに渡されます。
先ほど用意したJavaScriptのコードではkey1というキーの値を読み取っています。
レスポンスのステータスが202であれば成功しています。ただし、実際には非同期で実行されます。
また、指定したfunctionが存在しない場合やその他のエラーが発生した場合は例外が発生しますので適切に処理してください。
Lambdaでconsole.logした場合の出力はCloudWatch Logsに出力されますのでこちらを確認してみます。
マネージメントコンソール上でCloudWatchからのLogsにfunction名と同じLog Groupが存在しているので実行したfunction名のものを表示してみてください。
なお、このプログラムを実行するユーザにはlambda:InvokeAsyncの権限が必要となりますので、このプログラムを実行するIAMのUserもしくはRoleにPolicyで許可しておいてください。
こんな感じでAWS LambdaとAWS SDK for Rubyを使ってEC2を使わずにサーバサイドの処理を実行することが可能になります。
たった10数行書くだけでEC2立ててゴニョゴニョしたりしなくていいのは非常に楽ですね。
最後に、大人のたしなみとしてお約束の文章を書いておきます。
免責
こちらは個人の意見で、所属する企業や団体は関係ありません。