12/01 AWS Lambda with Serverless Framework

2020/12/02に公開

この記事は、Serverless Hello World Advent Calendar 2020の1日目です。

Serverless Framerowkの導入

npmでグローバルにserverlessを入れてあげれば良いです。

% npm install -g serverless
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
/home/masa/.nodebrew/node/v14.15.1/bin/serverless -> /home/masa/.nodebrew/node/v14.15.1/lib/node_modules/serverless/bin/serverless.js
/home/masa/.nodebrew/node/v14.15.1/bin/sls -> /home/masa/.nodebrew/node/v14.15.1/lib/node_modules/serverless/bin/serverless.js

> serverless@2.14.0 postinstall /home/masa/.nodebrew/node/v14.15.1/lib/node_modules/serverless
> node ./scripts/postinstall.js


   ┌───────────────────────────────────────────────────┐
   │                                                   │
   │   Serverless Framework successfully installed!    │
   │                                                   │
   │   To start your first project run 'serverless'.   │
   │                                                   │
   └───────────────────────────────────────────────────┘

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules/serverless/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ serverless@2.14.0
updated 1 package in 13.533s

サービスの作成(とAWSアカウントの設定)

オプション付けずにslsコマンド(serverlessコマンドの短縮エイリアス)を打つと、インタラクティブに聞いてきてくれます。

事前にAWSのクレデンシャルを設定するのを忘れていたのでここで聞いてきました。

% sls 

Serverless: No project detected. Do you want to create a new one? Yes
Serverless: What do you want to make? AWS Node.js
Serverless: What do you want to call this project? adventcalendar01

Project successfully created in 'adventcalendar01' folder.

You can monitor, troubleshoot, and test your new service with a free Serverless account.

Serverless: Would you like to enable this? No
You can run the “serverless” command again if you change your mind later.


No AWS credentials were found on your computer, you need these to host your application.

Serverless: Do you want to set them up now? Yes
Serverless: Do you have an AWS account? Yes

If your browser does not open automatically, please open the URL: https://console.aws.amazon.com/iam/home?region=us-east-1#/users$new?step=final&accessKey&userNames=serverless&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess

Serverless: Press Enter to continue after creating an AWS user with access keys 
Serverless: AWS Access Key Id: AKI****
Serverless: AWS Secret Access Key: ****

AWS credentials saved on your machine at ~/.aws/credentials. Go there to change them at any time.

Serverless: Would you like the Framework to update automatically? Yes

Auto updates were succesfully turned on.
You may turn off at any time with "serverless config --no-autoupdate"

Serverless: Would you like to setup a command line <tab> completion? Yes
Serverless: Which Shell do you use ? zsh
Serverless: We will install completion to ~/.zshrc, is it ok ? Yes

Command line <tab> completion was successfully setup. Make sure to reload your SHELL.
You may uninstall it by running: serverless config tabcompletion uninstall

生成されたファイルの確認

serverless.ymlはぱっと見長いですが、コメントを消すとシンプルです。

service: adventcalendar01

frameworkVersion: '2'

provider:
  name: aws
  runtime: nodejs12.x

functions:
  hello:
    handler: handler.hello

関数本体のhandler.jsもシンプルです。関数に渡ってきたeventをレスポンスで返します。

'use strict';

module.exports.hello = async event => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Go Serverless v1.0! Your function executed successfully!',
        input: event,
      },
      null,
      2
    ),
  };

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};

デプロイ

sls deployでデプロイしてくれます。何やってるか見たいので-vも付けときます。

CloudFormationのスタックとしてデプロイされます。

% sls deploy -v
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - adventcalendar01-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_IN_PROGRESS - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_COMPLETE - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - adventcalendar01-dev
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service adventcalendar01.zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - adventcalendar01-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
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 - HelloLambdaVersion71PvgZ40DXsulRQD3wMYqpm3buZxst0g5fUvTLrgRg
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersion71PvgZ40DXsulRQD3wMYqpm3buZxst0g5fUvTLrgRg
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersion71PvgZ40DXsulRQD3wMYqpm3buZxst0g5fUvTLrgRg
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - adventcalendar01-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - adventcalendar01-dev
Serverless: Stack update finished...
Service Information
service: adventcalendar01
stage: dev
region: us-east-1
stack: adventcalendar01-dev
resources: 6
api keys:
  None
endpoints:
  None
functions:
  hello: adventcalendar01-dev-hello
layers:
  None

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:999999999999:function:adventcalendar01-dev-hello:1
ServerlessDeploymentBucketName: adventcalendar01-dev-serverlessdeploymentbucket-5x49q52doqr4


**************************************************************************************************************************************
Serverless: Announcing Metrics, CI/CD, Secrets and more built into Serverless Framework. Run "serverless login" to activate for free..
**************************************************************************************************************************************

HTTP GET APIにしてみる

serverless.ymlをこう直しました。下2行を追加しています。

functions:
  hello:
    handler: handler.hello
    events:
      - http: GET helloworld

sls deploy -vでデプロイし直します。

% sls deploy -v
Serverless: Deprecation warning: Starting with next major version, API Gateway naming will be changed from "{stage}-{service}" to "{service}-{stage}".
            Set "provider.apiGateway.shouldStartNameWithService" to "true" to adapt to the new behavior now.
            More Info: https://www.serverless.com/framework/docs/deprecations/#AWS_API_GATEWAY_NAME_STARTING_WITH_SERVICE
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service adventcalendar01.zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - adventcalendar01-dev
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloworld
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHelloworld
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceHelloworld
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloworldGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloworldGet
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloworldGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1606835405388
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1606835405388
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1606835405388
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - adventcalendar01-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - adventcalendar01-dev
Serverless: Stack update finished...
Service Information
service: adventcalendar01
stage: dev
region: us-east-1
stack: adventcalendar01-dev
resources: 11
api keys:
  None
endpoints:
  GET - https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev/helloworld
functions:
  hello: adventcalendar01-dev-hello
layers:
  None

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:999999999999:function:adventcalendar01-dev-hello:1
ServiceEndpoint: https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev
ServerlessDeploymentBucketName: adventcalendar01-dev-serverlessdeploymentbucket-5x49q52doqr4

endpointsの所に、設定したAPIのエンドポイントURLが表示されました。cURLで接続してみます。

% curl -v https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev/helloworld
*   Trying 143.204.83.120:443...
* TCP_NODELAY set
* Connected to XXXXXXXXXX.execute-api.us-east-1.amazonaws.com (143.204.83.120) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.execute-api.us-east-1.amazonaws.com
*  start date: May  7 00:00:00 2020 GMT
*  expire date: Jun  7 12:00:00 2021 GMT
*  subjectAltName: host "XXXXXXXXXX.execute-api.us-east-1.amazonaws.com" matched cert's "*.execute-api.us-east-1.amazonaws.com"
*  issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x559343a9b8c0)
> GET /dev/helloworld HTTP/2
> Host: XXXXXXXXXX.execute-api.us-east-1.amazonaws.com
> user-agent: curl/7.68.0
> accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200 
< content-type: application/json
< content-length: 3190
< date: Tue, 01 Dec 2020 15:12:10 GMT
< x-amzn-requestid: bcecfff3-caa8-49d0-9246-d5b7b458fbdf
< x-amz-apigw-id: W4ODnGCSoAMF9Fw=
< x-amzn-trace-id: Root=1-5fc65d4a-552e086a46c41d721addb713;Sampled=0
< x-cache: Miss from cloudfront
< via: 1.1 bb805b278d9e499bb4b90a28f311a7d9.cloudfront.net (CloudFront)
< x-amz-cf-pop: NRT12-C2
< x-amz-cf-id: Ownf-nlMDWzJ1nljXpaRrd2S9CfsvHpOtEz9cLRnrgzpTUKb1WUGkw==
< 
{
  "message": "Go Serverless v1.0! Your function executed successfully!",
  "input": {
(省略)
  }
* Connection #0 to host XXXXXXXXXX.execute-api.us-east-1.amazonaws.com left intact
}

上のソースコードに書いてある通り、eventの中身が取れました。

Discussion