AWS Lambda の関数を Ruby でつくってみます。
最近、Railsの実装で進めるときにシステムのモノリス感がひどいなぁと感じたりで、サーバーレス関連が気になっていて、その一環です。
参考
- AWS - AWS Lambda を Amazon API Gateway に使用する
- AWS - AWS Lambda コンソールで関数を設定する
- AWS - AWS Command Line Interface での AWS Lambda の使用
- Qiita - [AWS] Lambda 関数を AWS CLI を使ってデプロイする
- AWS Lambda の Ruby ランタイムを試す
- github - faker-ruby/faker
- [アップデート] AWS LambdaがRuby 2.7をサポートしました!
- AWS Lambda に Ruby 関数をデプロイするために zip ファイルをつくる
- AWSのLambda上でRubyを動かしてJSONを返す関数を作成する
- dockerhub - amazon/aws-lambda-ruby
- github - shyouhei/ruby-uuid
作成
Lambda 関数の作成
Lambda の設定を開き「関数の作成」を押下
「一から作成」を選択し、関数名とランタイムを設定
任意の関数名と、ランタイムを選択します。トリガーを追加する
トリガーを設定します
API Gateway、HTTP API、セキュリティをオープンで設定しました。APIエンドポイント を確認
確認したエンドポイントにアクセス
Hello from Lambda!
の表示が確認きます。
Hello from Lambda!
の呼び出しはどこから?
Hello from Lambda!
の記載があるコードは、「関数コード」のエディタ部分で確認できます。
これは定義だけで、呼び出し部分は「ランタイム設定」のハンドラ部分に記載がありました。
関数コードを編集し、「Deploy」で反映できます。
アップロード 1
Lambda関数でAPIを作ることはできましたが、「関数コード」のエディターだけで作業を続けるのは、苦しいです。
ローカルで開発してアップロードできるようにします。
IAM ロールの作成
ローカルからアップロードを行うために、IAM ロールを作成します。
IAM の設定を開き、「ユーザーを追加」を押下
設定 1
任意のユーザー名と アクセスの種類に「プログラムによるアクセス」を設定します。設定 2
アクセス許可設定で、AWSCodeDeployRoleForLambda
を設定します。設定 3
「タグ追加」がありますが、今回は特に不要なのでスキップします。設定 4
内容確認して進めます。設定 5
アクセスキーと、シークレットアクセスキーを後で使うので控えておきます。
AWS CLI の導入
AWS CLI 各プラットフォームに即して導入します。
AWS CLI バージョン 2 のインストール、更新、アンインストール
今回は、Windows 環境に導入しました。
続けて AWS CLI に鍵情報を含めた設定をするため、以下の通り実行します。
1 | $ aws configure |
開発環境作成
開発環境の用意に当たり、今回もDockerで環境を用意しました。
1 | FROM amazon/aws-lambda-ruby |
1 | version: "3" |
(port設定があるのは、作った関数をローカルでの呼び出せないか試みた名残です)
以下操作で使用します。
1 | $ docker-compose build |
lambda_function.rb
を作成します。
1 | require 'json' |
とりあえず、自動作成されたメソッドと同じもので比較用に出力文字列変えたものを用意します。
(意味合い上英文は合っていないやもしれない。)
コンテナ内で、以下を実行し、lambda_function.rbをlambda.zipに固めます。
1 | $ zip lambda.zip lambda_function.rb |
コンテナから出るか、別のコンソールで以下コマンドを実行しアップロードします。
1 | $ aws lambda update-function-code --function-name test_func --zip-file fileb://lambda.zip |
--function-name
の部分は関数の名前です。fileb://
の後ろにアップロードするファイル名を指定します。
エンドポイントにアクセスすると、表示内容が変更されています。
ローカルで作成したファイルをアップロードできました。
アップロード 2
現在の実行内容は標準のランタイムに含むパッケージしか使用していません。
外部のgemを導入してみます。
コンテナ内で、以下を実行します。
1 | $ bundle init |
.env を作成し以下を記載します。
1 | NAME=TEST-APP |
lambda_function.rb
を導入した、uuid
dotenv
を使用するように書き換えます。
1 | # 標準パッケージ |
できたら、以下コマンドで、zipに固めます。
1 | $ zip -r lambda.zip . |
.
を指定して、vendor
以下もまとめてzipに固めています。
再度コンテナから出るか、別のコンソールで以下コマンドを実行しアップロードします。
1 | $ aws lambda update-function-code --function-name test_func --zip-file fileb://lambda.zip |
エンドポイントにアクセスすると、以下のように表示されます。
外部のgemを利用した、Lambda関数が作成できました。
パラメーターを受け付ける
API にはパラメータを投げつけたくなるものです。
パラメーターを付与してみます。
API Gateway を REST API に変更
最初に作ったのは、HTTP APIでした。
こちらをREST APIに切り替えます。
一度作成したAPIを削除
「トリガーを追加」
REST APIを作成
エンドポイントを確認しておく
実装
lambda_function.rb
をパラメータを受け付けるように書き換えます。
1 | require 'json' |
event["queryStringParameters"]
は、文字列のパラメータ。event["multiValueQueryStringParameters"]
は配列のパラメータを引き受けます。
確認
パラメータを渡すために、REST クライアントでアクセスします。
引き渡したパラメータを、レスポンスとして返してくるようになりました。
同じ名前でパラメータを渡すと、event["multiValueQueryStringParameters"]
では上書きせず、配列として処理してくれました。
今回の実装ではやっていませんが、event には HTTP メソッドの情報も載ってくるのでそれらでのコントロールも可能でした。
今回は、AWS Lambda を触ってみました。
普段触る AWS の機能があまりにも限定的なので、権限回りなど四苦八苦でしたがどうにか使えました。
実は今回、Faker gem をAWS Lambdaで動作させようとしたものの、どうしても動作できず断念しています。
理由をつかめていないところは残念です。
今度は、AWS Lambda から 何かしらDBへの接続を試みてみたいところです。
ではでは。