Posted at

Serverless Frameworkでお手軽サーバーレス(基本編)

Lambdaでお手軽サーバーレス入門の次の記事(とりあえず作ってみる編)(API Gateway設定編)(API Gatewayデプロイ編)(CloudWatch Events編)で、軽くLambda、API Gateway、CloudWatch Eventsについて紹介しました。


問題


  • 関数そのものを作るより設定のほうが手間

  • 設定を手動でするなんてナンセンス


解決策

Serverless Frameworkを使おう!


できること

たくさんありますが、以下のようなことが実現できます。


  • Lambda関数のデプロイ

  • トリガーの設定(API Gateway, CloudWatch Events, SNSなど…)

  • プラグインの使用


前提

Serverless FrameworkはNodeで動くので、以下のツールをインストールしておいてください。


  • Node.js (4.0以上)

  • AWS CLI


インストール・セットアップ

npm install -g serverless

私のところではこのような感じです。

slsserverlessのエイリアスです。)

$ node -v

v8.11.4

$ npm -v
5.6.0

$ sls --version
1.27.3

$ aws --version
aws-cli/1.16.1 Python/3.7.0 Darwin/18.0.0 botocore/1.11.1

インストールが終われば、AWSのアクセスキーを設定します。

(既に設定済みであればパスして問題ありません)

sls config credentials --provider aws --key AWSACCESSKEY --secret AWSSECRETACCESSKEY


定義ファイル

Serverless Frameworkでは、デプロイしたいサービスごとに、定義ファイル serverless.yml を作成する必要があります。


簡単なサンプル

以下のファイルを、Lambdaでお手軽サーバーレス入門(Lambdaのイベント from API Gateway編)で作ったディレクトリに置きます。

image.png


serverless.yml

service: qiita-lambda-apigateway

provider:
name: aws
profile: ${opt:profile, 'default'}
stage: prod
region: ap-northeast-1
runtime: python3.6
role: arn:aws:iam::ACCOUNT_ID:role/service-role/YOUR-ROLE-NAME # 適切なロール名に置き換えてください!
timeout: 30
memorySize: 128
versionFunctions: false

resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: ${self:service}-${self:provider.stage}

package:
individually: true

custom:
prefix: ${self:service}-${self:provider.stage}

functions:
lambda_function:
name: ${self:custom.prefix}-lambda_function
handler: lambda_function.lambda_handler
events:
- http:
integration: lambda-proxy
path: hello-world
method: GET
cors: true
- http:
integration: lambda-proxy
path: hello-world/{id}
method: GET
cors: true
- http:
integration: lambda-proxy
path: hello-world
method: POST
cors: true



何をするか簡単に解説


  • サービス名は qiita-lambda-apigateway

  • リージョンは東京

  • ランタイムは Python3.6

  • タイムアウトは30秒

  • メモリは128MB確保

  • 関数 lambda_function を定義


    • ハンドラーは lambda_function.lambda_handler

    • イベント定義は3つ


      • HTTP (API Gateway)


        • GET /hello-world

        • GET /hello-world/{id}

        • POST /hello-world

        • CORSをすべて有効にする








早速デプロイする

ターミナルを開き、serverless.ymlのあるディレクトリで、以下のコマンドを実行します。

serverless deploy

# serverless deploy --verbose # 詳細を見たいとき

このような感じでログが出力されます。

Serverless: Packaging service...

Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - qiita-lambda-apigateway-prod
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 - qiita-lambda-apigateway-prod
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (6.73 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - qiita-lambda-apigateway-prod
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - LambdaUnderscorefunctionLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - LambdaUnderscorefunctionLogGroup
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - LambdaUnderscorefunctionLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloDashworld
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - LambdaUnderscorefunctionLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloDashworld
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceHelloDashworld
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - LambdaUnderscorefunctionLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - LambdaUnderscorefunctionLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldOptions
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloDashworldIdVar
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldOptions
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloDashworldIdVar
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceHelloDashworldIdVar
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - LambdaUnderscorefunctionLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldPost
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldOptions
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - LambdaUnderscorefunctionLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldPost
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldGet
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldPost
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldIdVarGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldIdVarGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldIdVarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldIdVarGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldIdVarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloDashworldIdVarOptions
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1539166300519
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1539166300519
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1539166300519
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - LambdaUnderscorefunctionLambdaPermissionApiGateway
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - qiita-lambda-apigateway-prod
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - qiita-lambda-apigateway-prod
Serverless: Stack update finished...
Service Information
service: qiita-lambda-apigateway
stage: prod
region: ap-northeast-1
stack: qiita-lambda-apigateway-prod
api keys:
None
endpoints:
GET - https://**********.execute-api.ap-northeast-1.amazonaws.com/prod/hello-world
GET - https://**********.execute-api.ap-northeast-1.amazonaws.com/prod/hello-world/{id}
POST - https://**********.execute-api.ap-northeast-1.amazonaws.com/prod/hello-world
functions:
lambda_function: qiita-lambda-apigateway-prod-lambda_function

Stack Outputs
ServiceEndpoint: https://**********.execute-api.ap-northeast-1.amazonaws.com/prod
ServerlessDeploymentBucketName: qiita-lambda-apigateway-serverlessdeploymentbuck-**********

よく見ると、CloudFormationが動いているようですね。

…はい、Serverless Frameworkは、あの鬼のようにややこしいCloudFormationのテンプレートを作ってくれて、実行してくれるツールです。


確認

それぞれ、コンソールを覗いてみましょう。


Lambda

sls01.png

赤枠で囲ったところに、CloudFormationのスタックに属していることが表示されていますね。


API Gateway

sls02.png

3つ設定したエンドポイントと、CORS用のOPTIONS、計5つが登録されています。

また、このエンドポイントは、↑のLambdaを呼び出すように設定されています。


CloudWatch Logs

sls03.png

ロググループも自動で作られます。

何も実行していないので、ストリームは空です。


まとめ

手動設定とはさよならしましょう!

前職の新人時代、製品のデプロイを任されたときは、手動デプロイしか方法がなかったのですが(今ならもう少し考えます…)、よく設定を忘れたり、ファイルを置き忘れたりして、市場問題と言われて叱責されたことが多々…。

そんなところで神経すり減らすより、使える自動化ツールはどんどん活用しちゃいましょう!