29
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Serverless Framework、Apex、SAMをちょっとだけさわってみて比較

Posted at

背景

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の形式で定義するとのことです。

serverless.yml
    :
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なリポジトリにコミットするにはちょっと嫌な感じです。

project.json
{
  "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テンプレートを生成するもとになるようです。
インデントにかなり違和感を感じます。

template.yaml
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に限定されないツールがいいという気持ちもあります。だったらそもそもそういうツールに限定して比較するべき

参考

29
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?