LoginSignup
5
3

More than 5 years have passed since last update.

AWS LambdaにServerless Frameworkを使ってみる

Posted at

はじめに

私はこれまでWebコンソールからポチポチと弄っていたのですが、設定を間違えて動かなくなることがあったので、コマンドラインでサクッとできたらいいなぁと思っておりました。
これを解決すべく、素晴らしいフレームワークが公開されておりますので、今回はこれを使ってみます。

執筆にあたり、以下の記事を参考にさせていただきました。
どうもありがとうございます😄

Serverless Frameworkならすぐ出来るよね AWSでサーバーレス(API+Lambda[java]を簡単セットアップ)

AWS Lambdaとは

AWS Lambda を使用すれば、サーバーのプロビジョニングや管理なしでコードを実行できます。
課金は実際に使用したコンピューティング時間に対してのみ発生し、コードが実行されていないときには料金も発生しません。

魔法のような言葉が羅列していますが、実際にWebコンソールから使ってみると、ソースコード、ビルド、デプロイがバラバラになり、使い勝手が良くありません。

そこで、そこら辺のソリューションをフレームワークとして提供してくれるのがServerless Frameworkです。
Serverless Frameworkでは、LambdaのTemplateとして、以下が用意されています。
今回は、aws-java-gradleを採用します。

  • aws-nodejs
  • aws-python
  • aws-java-maven
  • aws-java-gradle
  • aws-scala-sbt
  • aws-csharp

事前準備

設定済みの方は不要です。
私の開発環境は、MacOSXとなっております。

あまり詳しいことは書いておりませんので、ご了承ください。

環境のセットアップ

Serverless Framework

Serverless Frameworkのインストール

npmコマンドを使って、serverlsss Frameworkをインストールします。

$ node -v
v7.5.0
$ npm install -g serverless
$ serverless —version
1.27.2

nodeやnpmが使えない方は、Homebrewからインストール可能です。
スクリプトをターミナルに貼り付け実行して下さい。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

AWS CLIのインストール

コマンド内部で、AWS CLIを叩くのでインストールします。
(インストール済みの場合は、読み飛ばしてください)

$ pip install awscli

必要な権限のあるIAMユーザを用意し、設定をします。
(詳細は調べていません)

$ aws configure
AWS Access Key ID [None]:(Access Key)
AWS Secret Access Key [None]:(Secret Key)
Default region name [None]: ap-northeast-1
Default output format [None]:json

アプリケーションの作成

hello world的なものを作成します。

Serviceの作成

まずはテンプレートを作成します。
プロジェクト名は、myServiceとしました。適宜変更してください。

$ serverless create --template aws-java-gradle --path myService
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/hogehoge/Documents/myService"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.27.2
 -------'

Serverless: Successfully generated boilerplate for template: "aws-java-gradle"

Eclipseにインポート

Eclipseを起動して、Project Explorer -> 右クリック -> Gradle -> Existing Gradle Projectsで先程作成した「myService」フォルダを選択します。

serverless.ymlの修正とBuild

serverless.ymlの20行目あたりにある設定を変更します。

serverless.yml
provider:
  name: aws
  runtime: java8
  stage: prod
  region: ap-northeast-1

せっかくなのでコマンドラインから、ビルド出来るか試してみます。
Eclipseから実行する場合は、Gradleタスクの実行からbuildを選択してください。

$ gradle build
Starting a Gradle Daemon (subsequent builds will be faster)

BUILD SUCCESSFUL in 8s
4 actionable tasks: 4 executed

$ ls -l build/libs
total 16
-rw-r--r--  1 hogehoge  staff  4907  5 15 10:04 myService.jar

LambdaのみDeployしてみる

Serveress Frameworkでは、Lambdaのセットアップ、JarのアップロードをCloudFormationを使って実行します。
これで Lambda関数に myService-prod-hello が出来ていればOKです。
WebコンソールでLambdaを設定して、Jarアップロードして...面倒な作業が不要となります。

$ cd myService
$ serverless deploy -v
Serverless: Packaging service...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - myService-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 - myService-prod
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (1.81 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - myService-prod
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
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 - HelloLambdaVersionAMFqcDHAse48pHCLO4T8bZ0tcLP0S5hwaqiXFZhekc
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersionAMFqcDHAse48pHCLO4T8bZ0tcLP0S5hwaqiXFZhekc
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersionAMFqcDHAse48pHCLO4T8bZ0tcLP0S5hwaqiXFZhekc
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - myService-prod
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - myService-prod
Serverless: Stack update finished...
Service Information
service: myService
stage: prod
region: ap-northeast-1
stack: myService-prod
api keys:
  None
endpoints:
  None
functions:
  hello: myService-prod-hello

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:************:function:myService-prod-hello:1
ServerlessDeploymentBucketName: myservice-prod-serverlessdeploymentbucket-n1n0p0oovbe7

テスト

早速動くかテストしてみましょう。
テストケースを作成してから実行します。

echo '{"key1":"value1","key2":"value2","key3":"value3"}' > event.json
$ serverless invoke --function hello -p event.json
{
    "statusCode": 200,
    "body": "{\"message\":\"Go Serverless v1.x! Your function executed successfully!\",\"input\":{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}}",
    "headers": {
        "X-Powered-By": "AWS Lambda & serverless"
    },
    "isBase64Encoded": false
}

API Gateway+Lambdaの構成でデプロイ

上記手順では、endpoints がありません。
API Gateway+Lambdaとなるよう、設定を変更後にDeployします。
serverless.ymlの51行目周辺のfunction句を書き換えます。

serverless.yml
functions:
  hello:
    handler: com.serverless.Handler
    events:
      - http:
          path: users/create
          method: get

Deployしてみます。
Amazon API Gatewayにprod-myServiceが作成されます。

$ serverless deploy -v
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (1.81 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - myService-prod
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceUsers
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceUsers
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceUsers
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceUsersCreate
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceUsersCreate
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceUsersCreate
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodUsersCreateGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodUsersCreateGet
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodUsersCreateGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1526347394711
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1526347394711
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1526347394711
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - myService-prod
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - myService-prod
Serverless: Stack update finished...
Service Information
service: myService
stage: prod
region: ap-northeast-1
stack: myService-prod
api keys:
  None
endpoints:
  GET - https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/prod/users/create
functions:
  hello: myService-prod-hello

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:************:function:myService-prod-hello:1
ServiceEndpoint: https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/prod
ServerlessDeploymentBucketName: myservice-prod-serverlessdeploymentbucket-n1n0p0oovbe7

テスト

endpointに向けてリクエストして、反応するか確認します。

curl https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/prod/users/create | jq
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                               Dload  Upload   Total   Spent    Left  Speed
100  1541  100  1541    0     0   7820      0 --:--:-- --:--:-- --:--:--  7822
{
"message": "Go Serverless v1.x! Your function executed successfully!",
"input": {
  "resource": "/users/create",
  "path": "/users/create",
  "httpMethod": "GET",
  "headers": {
    "Accept": "*/*",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-Country": "JP",
    "Host": "**********.execute-api.ap-northeast-1.amazonaws.com",
    "User-Agent": "curl/7.54.0",
    "Via": "2.0 *********.cloudfront.net (CloudFront)",
    "X-Amz-Cf-Id": "************",
    "X-Amzn-Trace-Id": "Root=********",
    "X-Forwarded-For": "XXX.XXX.XXX.XXX, XXX.XXX.XXX.XXX",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "queryStringParameters": null,
  "pathParameters": null,
  "stageVariables": null,
  "requestContext": {
    "resourceId": "***",
    "resourcePath": "/users/create",
    "httpMethod": "GET",
    "extendedRequestId": "******************",
    "requestTime": "15/May/2018:01:27:55 +0000",
    "path": "/prod/users/create",
    "accountId": "************",
    "protocol": "HTTP/1.1",
    "stage": "prod",
    "requestTimeEpoch": *****,
    "requestId": "********-****-****-****-************",
    "identity": {
      "cognitoIdentityPoolId": null,
      "accountId": null,
      "cognitoIdentityId": null,
      "caller": null,
      "sourceIp": "XXX.XXX.XXX.XXX",
      "accessKey": null,
      "cognitoAuthenticationType": null,
      "cognitoAuthenticationProvider": null,
      "userArn": null,
      "userAgent": "curl/7.54.0",
      "user": null
    },
    "apiId": "hogehoge"
  },
  "body": null,
  "isBase64Encoded": false
  }
}

Stackの削除

上記で作成したCloudFormationのStackごと削除できます。

$ serverless remove
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
................
Serverless: Stack removal finished...

参考

Serverless Frameworkならすぐ出来るよね AWSでサーバーレス(API+Lambda[java]を簡単セットアップ)

5
3
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
5
3