背景
Serverless Framework、Apex、SAMなど、Lambdaを管理できるツールはたくさんあります。
どれがどんなものなのかイマイチ分からなかったため、Hello World程度動かしながら比較しました。
環境
- Mac OS X
- Serverless Framework
- 1.35.0
- Apex
- 1.0.0-rc2
- SAM CLI
- 0.9.0
Hello Worldしてみる
Serverless Framework
インストール
$ npm install -g serverless
AWSのクレデンシャルはServerless FrameworkでもApexでもSAMでも、~/.aws/credentials を読み込んだりしてくれるとのことです。
プロジェクト作成
sls create
コマンドにより、最小限のテンプレートが生成されます。
$ sls create -t aws-nodejs -p my-service
$ ls my-service
handler.js serverless.yml
serverless.yml
serverless.yamlに環境やイベントが定義できます。
Lambda以外のリソースはCloudFormationの形式で定義するとのことです。
:
service: my-service # NOTE: update this with your service name
:
provider:
name: aws
runtime: nodejs8.10
:
# you can overwrite defaults here
# stage: dev
# region: us-east-1
:
# you can add statements to the Lambda function's IAM Role here
# iamRoleStatements:
# - Effect: "Allow"
# Action:
:
# you can define service wide environment variables here
# environment:
# variable1: value1
:
# you can add packaging information here
#package:
# include:
# - include-me.js
# - include-me-dir/**
# exclude:
# - exclude-me.js
# - exclude-me-dir/**
:
functions:
hello:
handler: handler.hello
:
# The following are a few example events you can configure
# NOTE: Please make sure to change your handler code to work with those events
# Check the event documentation for details
# events:
# - http:
# path: users/create
# method: get
# - s3: ${env:BUCKET}
:
# Define function environment variables here
# environment:
# variable2: value2
:
# you can add CloudFormation resource templates here
#resources:
# Resources:
:
サービスと関数のデプロイ
sls deploy
で、CloudFormationのStackが作成されます。
$ cd my-service
$ sls deploy -v
$ sls deploy function -f hello
関数の実行
sls invoke
で関数を実行できます。
$ sls invoke -f hello
{
"statusCode": 200,
"body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":{}}"
}
標準入力などからデータを渡すこともできます。
プロジェクト削除
$ sls remove
全てCloudFormationで構築されているため、きれいに削除されます。
実行時に「ほんとに消していいの?」みたいな確認はありませんでした。
Apex
インストール
$ curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh
内部でGitHub APIを利用しているため、GitHub APIの制限による403 Forbiddenで何度かインストールが失敗しました。
その場合、時間を置いて再度インストールを試みましょう。
プロジェクト作成
apex init
でテンプレートが生成されます。
Serverless FrameworkやSAMと異なり、カレントディレクトリに生成されるので注意が必要です。
$ apex init
$ tree
.
├── functions
│ └── hello
│ └── index.js
└── project.json
2 directories, 2 files
functions 以下にディレクトリを追加すると、自動で新たな関数として認識してくれます。
project.json
Serverless FrameworkやSAMと異なりCloudFormationを利用していないため、project.jsonにIAM RoleのARNが記載されます。
publicなリポジトリにコミットするにはちょっと嫌な感じです。
{
"name": "sample",
"description": "",
"memory": 128,
"timeout": 5,
"role": "arn:aws:iam::xxx:role/sample_lambda_function",
"environment": {}
}
Lambda以外のリソースは apex infra
というコマンドで扱います。
apex infra
はTerraformのラッパで、リソースをTerraformのテンプレートで定義することになります。
関数のデプロイ
$ apex deploy
めちゃくちゃ簡単です。
関数の実行
$ apex invoke hello
{"hello":"world"}
プロジェクト削除
$ apex delete
Lambda関数は消えていましたが、IAM RoleやCloudWatch Logsのロググループは消えませんでした。。。
何に紐づいているか分からないIAM Roleやロググループが残るのは個人的にはあまり好きでないです。
SAM
インストール
Installing AWS SAM CLI on macOS の通りの手順でインストールします。
$ brew tap aws/tap
$ brew install aws-sam-cli
プロジェクト作成
$ sam init --runtime nodejs8.10
$ tree sam-app
sam-app
├── README.md
├── hello-world
│ ├── app.js
│ ├── package.json
│ └── tests
│ └── unit
│ └── test-handler.js
└── template.yaml
3 directories, 6 files
sam-appディレクトリ以下にテンプレートが生成されます。
template.yaml
template.yamlは、CloudFormationテンプレートを生成するもとになるようです。
インデントにかなり違和感を感じます。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs8.10
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
PARAM1: VALUE
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
デプロイの準備
node_modulesなどの依存関係をインストールします。
$ sam build --use-container
コードを保存するS3バケットを作成します。
$ aws s3 mb s3://bucketname
デプロイのため、CloudFormationのテンプレートを生成します。
$ sam package \
--output-template-file packaged.yaml \
--s3-bucket bucketname
関数のデプロイ
$ sam deploy \
--template-file packaged.yaml \
--stack-name sam-app \
--capabilities CAPABILITY_IAM \
--region us-east-1
関数の実行
マネジメントコンソールからCloudFormationの出力を確認してURLにアクセスします。
{"message":"hello world","location":"xxx.xxx.xxx.xxx"}
ローカルでのテスト
チュートリアルに関数のテストについて書かれていたので、試してみました。
$ sam local start-api
この状態で http://localhost:3000/hello を叩くと、ローカルで関数が実行されます。
このタイミングでDockerイメージがダウンロードされて起動するので、コンソールを見ているとカッコいいです。
ホットデプロイされるらしく、開発時は嬉しいかもしれません。
ちなみに、Serverless FrameworkやApexのドキュメントには、ビジネスロジックを分離することで単体テスト可能にしろと書かれています。
特にApexはローカルでテストすることを想定していないようです。
分かった特徴
Serverless Framework
- AWS以外にも対応している
- CloudFormationで全て管理される
- シンプルに使えるが、がっつり使っていくこともできそうな気がする
- なんとなくよく聞くし、評価高い気がする (ソースはない)
Apex
- AWS Lambdaに特化したフレームワーク
- リソースがあまり管理されておらず、
apex delete
しても一部のリソースは残ってしまう - Lambda以外のリソースをデプロイするには、Terraformテンプレートを利用する
- テストをローカルで行うことは想定していない
- シンプルだけどがっつり使うと辛いかも (個人的な感想)
SAM
- AWS公式のフレームワーク
- コードを保存するS3以外のリソースはCloudFormationで管理される
- ローカルでAPIとしてテスト可能
- デプロイまでの手順が多い
自分なりの結論
Apexはリソースを管理しきれていないこと、SAMはデプロイまでの手順が多いと感じたことから、この3つの中ではServerless Frameworkが気に入りました。
どうせ勉強するならAWSに限定されないツールがいいという気持ちもあります。だったらそもそもそういうツールに限定して比較するべき