概要
Serverless Framework は AWS lambda のような Function as a Service を制御することができるツールです
同じようなツールに SAM などがあります
AWS の他にも Azure Functions や Google Cloud Functions を制御することができます
今回は AWS lambda を serverless コマンドを使って制御してみました
環境
- serverless 1.36.3
serverless のインストール
npm install -g serverless
執筆時点では homebrew にもありましたが公式が npm なので一応 npm でインストールしました
サービスの作成
serverless create --template aws-ruby --path my-service
デプロイする
serverless deploy -v
これで CloudFormation と S3 および lambda にデプロイできます
自分は aws-cli の設定をすでに行っていたので特に認証などは聞かれませんでしたがもしかすると設定しないとエラーになるかもしれません
ログを見るとわかりますが SAM を使って lambda にパッケージをデプロイする手順と同様で CloudFormation にスタックを作成し S3 にアップロードし関数を lambda に登録しています
ログは以下の通りです
(node:15694) ExperimentalWarning: The fs.promises API is experimental
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - my-service-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - my-service-dev
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (266 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - my-service-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersionenksLCJimutTnYkvXQRxsj92mdxvgp6T4iHWfW8IcvA
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersionenksLCJimutTnYkvXQRxsj92mdxvgp6T4iHWfW8IcvA
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersionenksLCJimutTnYkvXQRxsj92mdxvgp6T4iHWfW8IcvA
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - my-service-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - my-service-dev
Serverless: Stack update finished...
Service Information
service: my-service
stage: dev
region: us-east-1
stack: my-service-dev
api keys:
None
endpoints:
None
functions:
hello: my-service-dev-hello
layers:
None
Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:370162190418:function:my-service-dev-hello:1
ServerlessDeploymentBucketName: my-service-dev-serverlessdeploymentbucket-t8k07ycfl0of
デフォルトのリージョンは us-east-1
になっているようです
関数を実行する
serverless invoke -f hello
これで lambda に登録した関数を実行できます
JSON が返ってくれば OK です
serverless logs -f hello -t
で関数のログを監視することもできます
API Gateway トリガーと連携する
serverless.yaml を少し修正します
- vim serverless.yml
functions:
hello:
handler: handler.hello
events:
- http:
path: users/create
method: POST
events の部分がコメントになっているのでコメントアウトしましょう
特定のパスに POST でアクセスできるようにします
わかりやすくするため handler.rb も修正しましょう
- vim handler.rb
require 'json'
def hello(event:, context:)
begin
raise if event['body'].nil?
{ statusCode: 200, body: JSON.generate(event['body']) }
rescue StandardError => e
{ statusCode: 400, body: JSON.generate("missing body") }
end
end
リクエストボディに body がない場合は 400 が返ってくるようにします
再デプロイ
serverless deploy -v
Service Information
service: my-service
stage: dev
region: us-east-1
stack: my-service-dev
api keys:
None
endpoints:
GET - https://g66hn8ycj7.execute-api.us-east-1.amazonaws.com/dev/users/create
functions:
hello: my-service-dev-hello
layers:
None
一部抜粋ですが endpoints が新たに表示されています
ここにアクセスして動作確認してみましょう
curl -X POST -d "hawk" https://g66hn8ycj7.execute-api.us-east-1.amazonaws.com/dev/users/create
これで -d
に指定した値が返ってくれば成功です
また -d
がない場合にエラーのメッセージが返ってくることも確認しましょう
クリーンアップ
serverless remove
これで CloudFormation 経由で S3 および lambda のリソースが削除されます
CloudFormation のスタックも削除してくれるようです
おまけ: ローカルで function のテストをするには
今回で言えば handler.rb のテストです
今回のケースのように簡単な処理であれば問題ないですが、普通に考えれば deploy する前にテストしたいものです
例えば以下のようにローカルテスト用のスクリプトを書いてユニットテストしたりできます
touch handler_test.rb
vim handler_test.rb
require './handler.rb'
require 'test/unit'
class TestHandler < Test::Unit::TestCase
def test_200()
response = hello(event: {'body' => 'hoge'}, context: {})
assert_equal 200, response[:statusCode]
assert_match /hoge/, response[:body]
end
def test_400()
response = hello(event: nil, context: {})
assert_equal 400, response[:statusCode]
assert_match /missing body/, response[:body]
end
end
ruby handler_test.rb
最後に
Serverless Framework を使って AWS lambda を制御してみました
lambda を直接使った際の煩わしさはないかなと思います
ただ使う場合には lambda の動きを理解していないと厳しいと思います
今回はトリガー (API Gateway) との連携も行いました
Layers の機能も扱えるようなので lambda の機能はほぼ使えると思います
SAM と比較すると定義ファイルを YAML で記述する点は変わりません
機能的にもほぼ同じなのでどちらを使っても良いかなと思います
Serverless Framework を使えば、lambda 以外の FaaS も制御できるのでやはりその点が大きいかなと思います
0 件のコメント:
コメントを投稿