初めてのサーバーレスアプリケーション開発 ~Serverless Framework を使ってAWSリソースをデプロイする~

2018.09.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

以前のエントリでは、GUIで簡単なサーバーレスアプリケーションを構築する方法を学びました。

GUIで入力内容を確認しながらリソースを作成しサービスに対する理解を深めることは重要なことです。ですが、実際の開発でGUIをポチポチするのはちょっと面倒ですよね。

ということで今回は、以前GUIで作成したAWSの各リソースをServerless Frameworkを使って一撃構築してみようと思います。また、次のブログではServerless FrameworkとAWSのCodeシリーズと連携させ、コード管理、デプロイ周りの自動化を実現していきたいと思います。

対象読者

  • サーバーレスアプリケーション開発未経験の方
  • サーバーレスに縁のないインフラエンジニアの方

本記事を実践して、Serverless Frameworkと仲良くなりましょう!!

それでは本題に入っていきます。

サーバーレスアプリケーション超入門

今回構築するアプリケーションの全体構成はこちら。

「クライアントからリクエストを受けて、DynamoDBの情報を返却する」簡単なアプリケーションを作成します。開発端末からServerless Frameworkのコマンドを実行することでAWS上のリソース(アプリケーション)をデプロイします。

Serverless Framework

Serverless Frameworkとは何なのか。公式ドキュメントよりserverless frameworkの概要を抜粋します。

The Serverless Framework is a CLI tool that allows users to build & deploy auto-scaling, pay-per-execution, event-driven functions.

Write your code, configure events to trigger your functions, then deploy & run those functions to your cloud provider via the Serverless CLI.

Serverless Frameworkの特徴

  • Node.jsを利用したフレームワーク
  • 自身で開発したファンクション、イベントをCLIを使って簡単にデプロイすることができる
  • AWS、Azure、GCPなど様々なプラットフォームに対してファンクションをデプロイすることができる

AWSをプラットフォームとした場合の挙動

  • ローカル環境でデプロイ対象となるLambdaファンクションやファンクションを実行するためのイベント(トリガー)、AWSのリソース等を定義
  • ローカル環境でデプロイコマンドを実行することで、AWS上でCloudFormationを実行し各種リソースを作成

Serverless Frameworkを利用すればローカルで開発したファンクションを簡単にAWS上にデプロイすることができます。

主要なコンポーネント

Serverless Frameworkの5つの主要なコンポーネントについても確認しておきましょう。

Service

Serverless Frameworkとして複数のリソースを管理するための単位です。このサービス内に以下の4つのコンポーネントを含めserverless.ymlとして定義します。

Functions

1つ以上のLambdaファンクションを定義します。

Events

Lambdaを実行するためのイベントを定義します。以下のようなイベントをLambdaファンクションのトリガーとして設定することが可能です。

  • API Gatewayのエンドポイントに対するhttpリクエスト
  • S3のputイベント
  • CloudWatchイベント(5分毎に実行など)
  • SNSトピック
  • CloudWatchアラート
  • などなど

Resources

Lambdaが利用するAWSのリソースを定義します。以下のようなリソースを作成することが可能です。

  • DynamoDB
  • S3バケット
  • SNSトピック
  • などなど

Plugins

プラグインを定義します。 例えばPythonで外部モジュールをインポートするためプラグインserverless-python-requirementsなどを利用することができます。

それでは早速やってみましょう!!

Serverless Framework実行環境構築

まずはServerless Frameworkの実行環境を構築していきます。

今回はAWSで利用可能な統合開発環境であるCloud9を使って環境を構築していきます。

ローカル端末にServerless Frameworkをインストールしたい方はこちらを参考にインストールを実施していただければと思います。

Cloud9環境構築

AWSマネジメントコンソールよりCloud9を選択します。

リージョンは東京に一番近いアジアパシフィック(シンガポール)としておきます。

次に「create environment」を選択後、Nameにdemo-cloud9を入力し「Next step」をクリックします。

Cloud9をホストするためのEC2に関する設定を入力します。今回はデフォルトの状態で「Next step」をクリックします。

「Create environment」をクリックします。

しばらくすると開発環境が立ち上がります。

画面の下部のターミナルよりCloud9をホストしているEC2のOS情報やライブラリを確認することができます。

$ cat /etc/system-release
Amazon Linux AMI release 2018.03
$ node -v
v6.14.4
$ npm --version
3.10.10

Serverless Frameworkインストール

ターミナルより以下のコマンドを実行しServerless Frameworkをインストールします。

$ npm install -g serverless
$ sls -v
1.30.1

Serverless Frameworkを利用するために必要な作業は以上です。ローカル端末でServerless Frameworkを利用する場合は別途Credentialsの設定が必要になります。Cloud9ではAWSコンソールにログインしたユーザーの権限で各種AWSリソースを操作できるのでCredentialsの設定作業は不要です。

以下のServerless Frameworkを利用する際には、AdministratorAccessの権限を持ったユーザー、もしくは各種リソースに対する権限を持ったユーザーでAWSコンソールにログインしてください。

サービス作成

Serverless Frameworkのサービスを作成します。今回はdemo-serviceというサービス名で、Python 3.6のLambdaファンクションを作成します。

$ serverless create --template aws-python3 --path demo-service
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/home/ec2-user/environment/demo-service"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.30.1
 -------'

Serverless: Successfully generated boilerplate for template: "aws-python3"

サービスが作成されました。

サービスを定義するためのファイルserverless.ymlには何が記載さえれているのでしょうか。ファイルを確認してみましょう。

serverless.yml

service: demo-service

provider:
  name: aws
  runtime: python3.6
  
functions:
  hello:
    handler: handler.hello

serverless.ymlには、サービス名、プロバイダー情報、そしてhelloという1つのファンクションが定義されています。

handler.pyも確認してみます。

handler.py

import json

def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

    # 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": event
    }
    """

handler.pyにはserverless.ymlで指定したhelloファンクションが定義されています。このファンクションはリクエストの内容をそのままレスポンスとして返却するようなコードになっています。

サービスを新規作成した状態では、1つのファンクションのみ定義されており、そのファンクションのトリガーとなるEventやファンクションが利用するResourceなどは存在していないことが確認できます。

サービスをデプロイする

今回は東京リージョンにデプロイしたいのでserverless.ymlregionを以下のように変更します。

service: demo-service

provider:
  name: aws
  runtime: python3.6
#  region: us-east-1  
  region: ap-northeast-1  

functions:
  hello:
    handler: handler.hello

demo-serviceディレクトリに移動した後、デプロイコマンドを実行します。

$ cd demo-service/
$ 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 - demo-service-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 - demo-service-dev
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
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 - HelloLambdaVersionP76m8XZ2HBRnXr9MMVFnRdDxr2s0qJkP3qrPHEVHYA
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersionP76m8XZ2HBRnXr9MMVFnRdDxr2s0qJkP3qrPHEVHYA
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersionP76m8XZ2HBRnXr9MMVFnRdDxr2s0qJkP3qrPHEVHYA
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - demo-service-dev
Serverless: Stack update finished...
Service Information
service: demo-service
stage: dev
region: ap-northeast-1  
stack: demo-service-dev
api keys:
  None
endpoints:
  None
functions:
  hello: demo-service-dev-hello

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:XXXXXXXXXXXX:function:demo-service-dev-hello:1
ServerlessDeploymentBucketName: demo-service-dev-serverlessdeploymentbucket-11wpbuf2ntlwf

CloudFormationにより必要なリソースを作成し、Lambdaファンクションをデプロイしていることが確認できます。

リソースの確認

作成されたリソースはAWSマネジメントコンソールからも確認できます。

AWSマネジメントコンソールよりCloudFormationを選択します。

「demo-service-dev」をクリックします。

リソースを表示します。

作成されたリソースが確認できます。明示的に指定しなくてもIAMロールやLogGroupが作成されていますね。

各サービスのメニューからもリソースを確認することができます。

Lambdaファンクションを実行する

以下のコマンドでデプロイされたLambdaファンクションを実行することができます。

$ sls invoke -f hello
{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}

問題なく実行できました。期待値通りの結果となっていますね。

DynamoDBを作成する

DynamoDBに以下のテーブルを作成します。serverless.ymlにDynamoDBのリソースを追加します。

  • テーブル名 : demo-sls-person
  • プライマリーキー : person_id(文字列)
  • ReadCapacityUnits : 5
  • WriteCapacityUnits : 5

serverless.yml

service: demo-service

provider:
  name: aws
  runtime: python3.6  
  region: ap-northeast-1

functions:
  hello:
    handler: handler.hello
    
resources:
  Resources:
    DemoDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          -
            AttributeName: person_id
            AttributeType: S
        KeySchema:
          -
            AttributeName: person_id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5
        TableName: demo-sls-person

デプロイコマンドを実行します。

$ sls deploy -v
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::DynamoDB::Table - DemoDynamoDbTable
CloudFormation - CREATE_IN_PROGRESS - AWS::DynamoDB::Table - DemoDynamoDbTable
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::DynamoDB::Table - DemoDynamoDbTable
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - demo-service-dev
Serverless: Stack update finished...
Service Information
service: demo-service
stage: dev
region: ap-northeast-1
stack: demo-service-dev
api keys:
  None
endpoints:
  None
functions:
  hello: demo-service-dev-hello

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:demo-service-dev-hello:2
ServerlessDeploymentBucketName: demo-service-dev-serverlessdeploymentbucket-3fun926drfcl

DynamoDBが作成されていることが確認できます。

テーブルが作成できたのでAWS CLIを使って項目を追加しておきましょう。

$ aws dynamodb put-item --table-name demo-sls-person --item '{"person_id": {"S": "001"}, "name": {"S": "tanaka"}}' --region ap-northeast-1
$ aws dynamodb put-item --table-name demo-sls-person --item '{"person_id": {"S": "002"}, "name": {"S": "suzuki"}}' --region ap-northeast-1
$ aws dynamodb put-item --table-name demo-sls-person --item '{"person_id": {"S": "003"}, "name": {"S": "yamada"}}' --region ap-northeast-1

Lambdaファンクションを修正する

次にLambdaファンクションを修正します。DynamoDBからperson_id:001を取得する簡単なコードです。

handler.py

import boto3
  
dynamodb = boto3.resource('dynamodb')
table    = dynamodb.Table('demo-sls-person')
  
def get_person(id):
    response = table.get_item(
            Key={
                 'person_id': id
            }
        )
    return response['Item']
          
def hello(event, context):
    person = get_person('001')
    return person

また、このLambdaファンクションにはDynamoDBに接続するための権限が必要であるため、serverless.ymlにIAMのポリシーの定義を追加します。

serverless.yml

service: demo-service

provider:
  name: aws
  runtime: python3.6
  region: ap-northeast-1  
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:*
      Resource: "*"  

functions:
  hello:
    handler: handler.hello
    
resources:
  Resources:
    DemoDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          -
            AttributeName: person_id
            AttributeType: S
        KeySchema:
          -
            AttributeName: person_id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5
        TableName: demo-sls-person

デプロイコマンドを実行します。

$ sls deploy -v
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
CloudFormation - UPDATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - UPDATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - demo-service-dev
Serverless: Stack update finished...
Service Information
service: demo-service
stage: dev
region: ap-northeast-1
stack: demo-service-dev
api keys:
  None
endpoints:
  None
functions:
  hello: demo-service-dev-hello

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:demo-service-dev-hello:8
ServerlessDeploymentBucketName: demo-service-dev-serverlessdeploymentbucket-f69k38xf2ifq

先ほどと同様にLambdaを実行してみましょう。

$ sls invoke -f hello
{
    "person_id": "001",
    "name": "tanaka"
}

期待する値が取得できました。

API Gatewayを作成する

最後にAPI Gatewayを作成します。API Gatewayを構築することでエンドポイントに対するGetリクエストをトリガーにLambdaを実行することができます。serverless.ymlにLambdaファンクションを呼び出すためのイベントを定義します。

serverless.yml

service: demo-service
 
provider:
  name: aws
  runtime: python3.6
  region: ap-northeast-1  
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:*
      Resource: "*" 
 
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: /
          method: get
          integration: lambda
          request:
            template:
              application/json: '{ "person_id" : "$input.params("person_id")" }'
resources:
  Resources:
    DemoDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          -
            AttributeName: person_id
            AttributeType: S
        KeySchema:
          -
            AttributeName: person_id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5
        TableName: demo-sls-person

Lambdaファンクションも以下のように修正しておきます。

handler.py

import boto3
   
dynamodb = boto3.resource('dynamodb')
table    = dynamodb.Table('demo-sls-person')
  
def get_person(id):
    response = table.get_item(
            Key={
                 'person_id': id
            }
        )
    return response['Item']
 
def get_persons():
    response = table.scan()
    return response['Items']
    
def hello(event, context):
    return get_persons() if event['person_id'] == '' else get_person(event['person_id'])

デプロイコマンドを実行します。

$ sls deploy -v
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (326 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
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::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodGet
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodGet
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1535528279760
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1535528279760
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1535528279760
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - demo-service-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - demo-service-dev
Serverless: Stack update finished...
Service Information
service: demo-service
stage: dev
region: ap-northeast-1
stack: demo-service-dev
api keys:
  None
endpoints:
  GET - https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/
functions:
  hello: demo-service-dev-hello

Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:demo-service-dev-hello:9
ServiceEndpoint: https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev
ServerlessDeploymentBucketName: demo-service-dev-serverlessdeploymentbucket-f69k38xf2ifq

デプロイが完了するとServiceEndpointが出力されます。このエンドポイントに対してGetリクエストを送ってみましょう。

$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev?person_id=001
{"person_id": "001", "name": "tanaka"}
$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev?person_id=002
{"person_id": "002", "name": "suzuki"}
$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev
[{"person_id": "001", "name": "tanaka"}, {"person_id": "003", "name": "yamada"}, {"person_id": "002", "name": "suzuki"}]

期待値通りの結果が出力されました!!

リソースの削除

一通り確認が終わったらAWS上のリソースを削除しておきましょう!

$ sls remove -v
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 - demo-service-dev
CloudFormation - DELETE_IN_PROGRESS - AWS::DynamoDB::Table - DemoDynamoDbTable
CloudFormation - DELETE_SKIPPED - AWS::Lambda::Version - HelloLambdaVersiondLmGUvM8VKQwAEAdFOUzBIZ4pbQaL2gtQuZCOpHhyM
CloudFormation - DELETE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1535606087043
CloudFormation - DELETE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - DELETE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1535606087043
CloudFormation - DELETE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodGet
CloudFormation - DELETE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodGet
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - DELETE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - DELETE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - DELETE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - DELETE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - DELETE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - DELETE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - DELETE_COMPLETE - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - DELETE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - DELETE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - DELETE_COMPLETE - AWS::DynamoDB::Table - DemoDynamoDbTable
Serverless: Stack removal finished...

さいごに

Serverless Frameworkを使えば、より手軽にサーバーレスアプリケーションを構築することができます。初めてのサーバーレスアプリケーション開発 ~Serverless Framework を使ってAWSリソースをデプロイする~では、今回作成したServerless FrameworkのサービスとCodeシリーズを組み合わせることで自動デプロイの仕組みを作成していきたいと思います。