Serverless FrameworkでLambda関数を作成

Serverless Frameworkを利用して、Lambda関数を作成します。API Gatewayのリクエストをトリガーに、Lambda関数が実行されるようにします。

作るもの

最終的な動作イメージを示します。

519-aws-lambda-introduction_image.png

【入門】LambdaとAPI Gatewayの使い方 にて、AWSの管理画面で手作業で作成したものと同じになります。

Serverless Frameworkをインストール

Node.jsのバージョンは v8.10.0 です。

$ node -v
v8.10.0

Serverless Frameworkをインストールします。

$ npm install -g serverless

インストールできました。

$ serverless --version
1.35.1

--helpオプション で使い方を確認できます。

$ serverless --help

Commands
* You can run commands with "serverless" or the shortcut "sls"
* Pass "--verbose" to this command to get in-depth plugin info
* Pass "--no-color" to disable CLI colors
* Pass "--help" after any <command> for contextual help

Framework
* Documentation: https://serverless.com/framework/docs/

config ........................ Configure Serverless
config credentials ............ Configures a new provider profile for the Serverless Framework
create ........................ Create new Serverless service
deploy ........................ Deploy a Serverless service
deploy function ............... Deploy a single function from the service
deploy list ................... List deployed version of your Serverless Service
deploy list functions ......... List all the deployed functions and their versions
info .......................... Display information about the service
install ....................... Install a Serverless service from GitHub or a plugin from the Serverless registry
invoke ........................ Invoke a deployed function
invoke local .................. Invoke function locally
logs .......................... Output the logs of a deployed function
metrics ....................... Show metrics for a specific function
package ....................... Packages a Serverless service
plugin ........................ Plugin management for Serverless
plugin install ................ Install and add a plugin to your service
plugin uninstall .............. Uninstall and remove a plugin from your service
plugin list ................... Lists all available plugins
plugin search ................. Search for plugins
print ......................... Print your compiled and resolved config file
remove ........................ Remove Serverless service and all resources
rollback ...................... Rollback the Serverless service to a specific deployment
rollback function ............. Rollback the function to the previous version
slstats ....................... Enable or disable stats

Platform (Beta)
* The Serverless Platform is currently in experimental beta. Follow the docs below to get started.
* Documentation: https://serverless.com/platform/docs/

login ......................... Login or sign up for the Serverless Platform
logout ........................ Logout from the Serverless Platform

Plugins
AwsConfigCredentials, Config, Create, Deploy, Info, Install, Invoke, Login, Logout, Logs, Metrics, Package, Plugin, PluginInstall, PluginList, PluginSearch, PluginUninstall, Print, Remove, Rollback, SlStats

sls と省略コマンドでも実行できます。さらに sls コマンド --help でコマンドの使い方について確認できます。

$ sls login --help
Plugin: Login
login ......................... Login or sign up for the Serverless Platform

認証情報設定

sls config

デプロイ時、AWSリソースの作成・管理を行う権限を持ったIAMユーザーが必要です。
ここでは、 Serverless Framework 用のIAMユーザーを作成しました。

sls config credentials --provider aws で作成したIAMユーザーの認証情報を設定します。
( aws configure と同じ要領で利用できます。)

$ sls config credentials --provider aws --key XXXXXXXXXXXXXXXXXXXX --secret XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --profile wakuwaku-sls-admin
Serverless: Setting up AWS...
Serverless: Saving your AWS profile in "~/.aws/credentials"...
Serverless: Success! Your AWS access keys were stored under the "wakuwaku-sls-admin" profile.

default設定済みなので、--profileオプション で新しいプロファイルとして設定しています。

サービスの作成

sls create

sls create でサービスを作成できます。

$ sls create --help
Plugin: Create
create ........................ Create new Serverless service
    --template / -t .................... Template for the service. Available templates: "aws-clojure-gradle", "aws-clojurescript-gradle", "aws-nodejs", "aws-nodejs-typescript", "aws-alexa-typescript", "aws-nodejs-ecma-script", "aws-python", "aws-python3", "aws-groovy-gradle", "aws-java-maven", "aws-java-gradle", "aws-kotlin-jvm-maven", "aws-kotlin-jvm-gradle", "aws-kotlin-nodejs-gradle", "aws-scala-sbt", "aws-csharp", "aws-fsharp", "aws-go", "aws-go-dep", "aws-go-mod", "aws-ruby", "azure-nodejs", "cloudflare-workers", "cloudflare-workers-enterprise", "fn-nodejs", "fn-go", "google-nodejs", "kubeless-python", "kubeless-nodejs", "openwhisk-java-maven", "openwhisk-nodejs", "openwhisk-php", "openwhisk-python", "openwhisk-ruby", "openwhisk-swift", "spotinst-nodejs", "spotinst-python", "spotinst-ruby", "spotinst-java8", "plugin" and "hello-world"
    --template-url / -u ................ Template URL for the service. Supports: GitHub, BitBucket
    --template-path .................... Template local path for the service.
    --path / -p ........................ The path where the service should be created (e.g. --path my-service)
    --name / -n ........................ Name for the service. Overwrites the default name of the created service.

今回はランタイムに node.js を利用したいので以下のように実行します。

$ sls create --template aws-nodejs
Serverless: Generating boilerplate...
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.35.1
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"
Serverless: NOTE: Please update the "service" property in serverless.yml with your service name

以下ファイルが生成されました。

$ ls
handler.js      serverless.yml

handler.jsを編集

Lambda関数を定義します。

今回は、以下の関数コードで動作確認をします。

'use strict'

module.exports.hello = async event => {
  console.log(event)
  console.log(process.env)

  let name = 'no name'
  if (event.queryStringParameters && event.queryStringParameters.name) {
    name = event.queryStringParameters.name
  }
  const response = {
    statusCode: 200,
    body: `Hello ${name}`,
  }
  return response
}

serverless.ymlを編集

Lambda実行環境の設定、関数とイベントの定義など行います。

service: sls-hello

provider:
  name: aws
  runtime: nodejs8.10
  profile: wakuwaku-sls-admin                                  # デプロイ時、リソースの作成・管理を行う権限を持ったIAMユーザーのprofile
  stage: dev
  region: ap-northeast-1
  role: arn:aws:iam::XXXXXXXXXXXX:role/lambda_basic_execution  # Lambda関数実行時のロール
  environment:
    WAKUWAKU: abcdefg
  timeout: 10
  memorySize: 128

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: message
          method: get

ローカルテスト

sls invoke local

sls invoke でテストできます。

$ sls invoke --help
Plugin: Invoke
invoke ........................ Invoke a deployed function
invoke local .................. Invoke function locally
    --function / -f (required) ......... The function name
    --stage / -s ....................... Stage of the service
    --region / -r ...................... Region of the service
    --path / -p ........................ Path to JSON or YAML file holding input data
    --type / -t ........................ Type of invocation
    --log / -l ......................... Trigger logging data output
    --data / -d ........................ Input data
    --raw .............................. Flag to pass input data as a raw string

ローカルでテストする場合、 sls invoke local を利用します。

$ sls invoke local --function hello --data '{"queryStringParameters":{"name":"wakuwaku"}}'
{ queryStringParameters: { name: 'wakuwaku' } }
{ SHELL: '/bin/bash',
    (省略)
  WAKUWAKU: 'abcdefg'}
{
    "statusCode": 200,
    "body": "Hello wakuwaku"
}

デプロイ

sls deploy

sls deploy でデプロイできます。

$ sls deploy --help
Plugin: Deploy
deploy ........................ Deploy a Serverless service
deploy function ............... Deploy a single function from the service
deploy list ................... List deployed version of your Serverless Service
deploy list functions ......... List all the deployed functions and their versions
    --conceal .......................... Hide secrets from the output (e.g. API Gateway key values)
    --stage / -s ....................... Stage of the service
    --region / -r ...................... Region of the service
    --package / -p ..................... Path of the deployment package
    --verbose / -v ..................... Show all stack events during deployment
    --force ............................ Forces a deployment to take place
    --function / -f .................... Function name. Deploys a single function (see 'deploy function')
    --aws-s3-accelerate ................ Enables S3 Transfer Acceleration making uploading artifacts much faster.

--verboseオプション を付与することでデプロイの進捗状況を確認できます。

$ sls deploy --verbose
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - sls-hello-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 - sls-hello-dev
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (298 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - sls-hello-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
        (省略)
Serverless: Stack update finished...
Service Information
service: sls-hello
stage: dev
region: ap-northeast-1
stack: sls-hello-dev
api keys:
  None
endpoints:
  GET - https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/message
functions:
  hello: sls-hello-dev-hello
layers:
  None

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:sls-hello-dev-hello:1
ServiceEndpoint: https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev
ServerlessDeploymentBucketName: sls-hello-dev-serverlessdeploymentbucket-xxxxxxxxxxxxx

作成されたリソース

CloudFormation

522-aws-serverless-framework_cloudformation.png

S3バケット Lambda関数 API Gatewayなどが作成されています。

API Gateway

522-aws-serverless-framework_api.png

デフォルトでLambda プロキシ統合の使用にチェックが入っているようです。

Lambda関数

522-aws-serverless-framework_lambda.png

serverless.ymlで設定した内容が反映されています。

動作確認

sls invoke

$ sls invoke --function hello --data '{"queryStringParameters":{"name":"wakuwaku"}}'
{
    "statusCode": 200,
    "body": "Hello wakuwaku"
}

curlでAPI呼び出し

$ curl https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/message?name=wakuwaku
Hello wakuwaku

問題なく動作しているようです。

サービスを削除

sls remove

sls remove で今回作成したサービスを削除します。

$ sls remove --verbose
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
CloudFormation - DELETE_IN_PROGRESS - AWS::CloudFormation::Stack - sls-hello-dev
    (省略)
CloudFormation - DELETE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
Serverless: Stack removal finished...

参考

https://serverless.com/framework/docs/

わくわくBank.
フリーランスのエンジニアとして活動してます。ここでは、ソフトウェア開発で必要とされる技術、用語、概念を整理しています。