2019年1月25日金曜日

AWS lambda 超入門 (Ruby 編)

概要

今更ながら AWS lambda に入門してみました
Ruby が動かせるようになっているので Ruby を使っています

環境

  • AWS lambda 2019/01/25 時点
  • Ruby 2.5

Hello World

まずは Hello World を出力してみます
lambda は何かしらのイベントをトリガーにして作成した関数を実行することができます

なのでまずは関数を作成します
UI 的には作成するための導線がたくさんあるので以下からでなくても OK えす
lambda1.png

「1 から作成」で必要な内容を入力していきます

  • 名前・・・hello_world_func
  • ランタイム・・・Ruby 2.5
  • ロール・・・「1 つ以上のテンプレートから新しいロールを作成します。」 
  • ロール名・・・hello_world_func_role
  • ポリシーテンプレート・・・「Amazon S3 オブジェクトの読み取り専用アクセス権限」

lambda2.png

ロールは作成した関数がどのリソースにアクセス可能なのかを指定します
とりあえず S3 にしておきます
問題なければ「関数の作成」を選択します

関数が作成されるとすでに Ruby のコードがあることがわかります
これを実行してみましょう
lambda3.png

「テスト」を選択します
するとイベントを作成する画面になると思います
冒頭に述べましたが lambda は何かしらのイベントを元にコードが実行されます
lambda4.png

上記のスクリーンショット上にはありませんが下の方に「作成」があるのでこれでテストイベントを作成します
イベントを作成したら「テスト」を再度押しましょう
これでイベントから関数が実行され結果が画面上に表示されます
lambda5.png

これが lambda の超基本的な流れと操作方法になります
あとはイベントや関数をカスタマイズしていく感じです

Rubygems と連携してみる

Ruby を使っているなら Rubygems で公開されているライブラリを lambda でも使いたくなります
結論から言うと使うことは可能ですが、先程とは違いかなりやり方が変わります

ローカルで環境を作成する

まずはローカルで環境と関数を作成します
適当に作業用のディレクトリを作成して移動しましょう

  • bundle init
  • vim Gemfile
gem "aws-sdk"
  • bundle install --deployment

今回は S3 にアクセスして指定のバケット配下にあるオブジェクトの一覧を取得したいと思います
事前に S3 にアクセスできるユーザの作成とバケットの作成を行っておきましょう
今回は「アジアパシフィック (シドニー) (ap-southeast-2)」に作成しました
lambda6.png

これらを取得するスクリプトを作成します

  • vim s3_test.rb
require 'aws-sdk'

$client = Aws::S3::Client.new(
  :region => 'ap-southeast-2',
  :access_key_id => 'xxxxxxxxx',
  :secret_access_key => 'xxxxxxxxxxx',
)

def list_objects(event:, context:)
  $client.list_objects(:bucket => 'lambda-test-12345').contents.map do |object|
    {:key => object.key }
  end
end

# p list_objects(event: nil, context: nil)

list_objects をコールして、一度ローカルで動作するか確認すると良いと思います
event および context の引数は必須になります
使わなくても宣言時には指定しましょう
また 2 つはイベント発生時に指定した JSON 情報になります
Ruby 内ではハッシュとして扱えるのでイベントから値を取得する場合などに参照してましょう

AWS SAM を使って関数を登録する

AWS SAM は Serverless Application Model の略でサーバレスアプリを YAML で記述することができるツールです
Cloud Formation の拡張で Cloud Formation と同じように定義します

sam コマンドのインストール

まず SAM コマンドをインストールします
awscli に依存しているので awscli もインストールします

  • brew install awscli
  • brew tap aws/tap
  • brew install aws-sam-cli

aws configure コマンドを使って初期化しましょう

sam テンプレートファイルの作成

次に今回の lambda 用の SAM テンプレートファイルを作成します

  • vim template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'sample s3 access ruby application'

Resources:
  S3TestFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: s3_test.list_objects
      Runtime: ruby2.5
      Policies:
      - S3ReadPolicy:
          BucketName: lambda-test-12345

Outputs:
  S3TestFunction:
    Description: Objects list
    Value:
      Fn::GetAtt:
      - S3TestFunction
      - Arn

Policies は SAM 用に定義されています
ここ に指定可能なポリシーの一覧を確認することができます
またポリシーを YAML で使うサンプルもあります
Outputs で指定している Fn::GetAtt では他の属性も指定できます
ここに指定可能な属性の一覧があります

S3 に関数を配置

このテンプレートファイルを使って一旦 S3 にローカルで作成したスクリプトを配置します

  • sam package --template-file template.yaml --output-template-file packaged-template.yaml --s3-bucket lambda-test-12345

lambda7.png

こんな感じでローカルで作成したスクリプトとライブラリが S3 にアップロードされています
今回はバケットは 1 つで行っていますがリソースファイルを配置するバケットと関数を配置するバケットは別でも問題ないです

関数を登録する 

そしてローカルに packaged-template.yaml という新しいテンプレートが作成されています
これを使って lambda に関数を登録します

  • sam deploy --template-file packaged-template.yaml --stack-name s3Test --capabilities CAPABILITY_IAM

以下のようになれば関数の登録が完了しています

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - s3Test

コンソールで確認してみましょう
lambda8.png

実行

あとは先程同様テスト用のイベントを作成して実行してみましょう
以下のようにちゃんとオブジェクトの一覧が取得できるのが確認できるはずです
lambda9.png

ちなみに関数を削除した場合は Cloud Formation 側に Stack も残っているのでそれも削除しましょう

Sinatra アプリをデプロイする

サンプルに API Gateway と lambda を連携して API サーバを構築する方法もあったのでやってみました
template.yaml などはすでにあるサンプルを使っています
AWS::Serverless::Api などが定義されているので興味があれば確認してみてください

  • git clone https://github.com/aws-samples/serverless-sinatra-sample.git
  • cd serverless-sinatra-sample
  • bundle install --deployment
  • sam package --template-file template.yaml --output-template-file packaged-template.yaml --s3-bucket lambda-test-12345
  • sam deploy --template-file packaged-template.yaml --stack-name LambdaSinatra --capabilities CAPABILITY_IAM

これで関数がデプロイされます
lambda10.png

左メニューからアプリケーションを選択すると API Gateway などの他のリソースの情報が確認できます
lambda11.png

API エンドポイントにアクセスすると Sinatra アプリが表示されます
/Prod/feedback でフィードバックアプリが /Prod/hello-world{"Output":"Hello World!"} という JSON が返ってきます

ちなみに SinatraApp 関数のログは CloudWatch に自動的に格納されています
lambda12.png

最後に

Ruby で AWS lambda に入門してみました
Rubygems を使う場合には一旦 S3 に関数を配置し SAM (Serverless Application Model) を使うことで関数を登録することができました

AWS の他のリソース (API Gateway や DynamoDB など) と連携する場合は SAM が必須なので実際のユースケースを考えると SAM の習得も必須かなと思います

参考サイト

0 件のコメント:

コメントを投稿