echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【Serverless Framework】簡単デプロイとserverless.ymlの記載について その1

※2019/6/27 Outputs項目に関する記載を追加しました。
※2019/6/27 さらにapiKeys/usagePlan/private項目に関する記載を追加しました。

概要

近日、仕事でAWSを触っていますが、その関係でServerless Frameworkを触ることになりました。

公式サイト:Serverless Framework

Serverless FrameworkはSAM同様、サーバーレスアプリ開発フレームワーク(正確にはテンプレートモデルに近い。Webアプリなどのフレームワークとはちょっと違う)CLIで、以下のことを行うことができます。

  • 環境(言語)ごとのテンプレートモデルの適用
  • 使用するリソース(Lambda、S3、DymnamoDBなど)の定義
  • コマンドライン上からの一括デプロイ(CloudFormationへの展開)

また、主に下記の点がSAMと異なります。

  • マルチクラウドプラットフォームである。(AWSだけでなく、AzureやGCPなどでも使える)
  • (ローカル環境での)デバッグ実行に、コンテナ(Dockerなど)が不要

があります。

ただ、公式ドキュメントが全編英語で、解説してるサイトもあまり多くなかったので、自分なりに「とりあえずデプロイ」できるところまでをまとめました。

インストール &プロジェクト作成

インストールは公式サイトのトップにもある通り、npm installをするだけです。(「-g」は必要に応じて置き換えてください。)

npm install -g serverless

プロジェクト作成は「serverless create」コマンドで作成します。

  • テンプレート名は言語別のテンプレート名。「aws-nodejs」「aws-python3」「aws-csharp」など。(詳細は公式ページを参照)
  • サービス名はアプリのプロジェクト名(≒アプリ名)。Serverless Frameworkでは「サービス」という扱いになる。
  • プロジェクトフォルダのパスはオプション。このフォルダがない場合、プロジェクト作成時に自動で作成して、そこをプロジェクトのルートにしてくれる。
# 「sls」は「serverless」の省略系。どちらでも実行可。
sls create --template (テンプレート名) --name (プロジェクト名)  --path (プロジェクトフォルダのパス)  
# e.g.  
sls create --template aws-nodejs --name makky12-serverless-fw-app --path makky12-dir

テンプレートファイル(serverless.yml) の定義

※これ以降は、AWSをベースに説明します。(それ以外の場合は、公式ドキュメントを参照)

serverless.ymlは、デプロイされるサービスの定義を行うファイルです。
(SAMのtemplate.ymlに該当)

つまりこの内容が、CloudFormationやLambdaなどの各種機能に設定されます。

ただこの公式ドキュメントのボリュームが大きいので、補足説明がいるなという項目だけ説明します。
(基本的なことは、公式の下記ページに書いてあります。全編英語ですが)

※プロジェクトに最初から入ってるhandler.jsを動かすだけなら、下記を設定してデプロイを実施するだけで、API Gateway経由でブラウザ実行できます。
(項目数は多いですが、ほとんどにデフォルト値が設定されてます。)

  • providerに「region: ap-northeast-1」を設定する。
  • 66 ~ 69行目(「events」~「method:get」)までのコメントを外す

ルート項目(インデントがない項目)

項目名 説明 備考
provider 複数項目で共通で使用する項目の値を設定する 項目別に上書き可能
custom serverless.yml内で使用する変数と値のペアを設定する 変数については後述
package プロジェクトをパッケージする際の設定をする
plugins 外部プラグインを使用する場合、プラグイン名を記入する 公式に書いてないんだけど...
functions Lambda関数の設定をする
resources プロジェクトで使用するリソース(S3/DynamoDBなど)の設定をする

provider項目

項目名 説明 備考
stage dev(開発)/stg(ステージング)など、環境が分かる設定をする 初期値はdev
〇〇name CloudFormation/API Gatewayなどで使用される名前 未指定の場合、デフォルト名がつけられる(プロジェクト名+αなど)
apiKeys 作成するAPIKeyの名前を指定する 配列で指定する
usagePlan 使用量プランの定義を指定する apiKeysに指定したAPIKeyに紐づく使用量プランとして登録される。
(なぜか)usagePlanName(使用量プラン名)は指定できない。(resourcesだと指定可能)
profile credentialを定義済の場合、そのプロファイル名を指定する デプロイの際、設定したプロファイルの認証情報を使用する
deploymentBucket パッケージされたファイルを格納するS3のバケット名を指定する 注意が必要。(後述)
role 全Lambda関数に適用される共通のIAMロールを設定する
iamRoleStatements Lambda関数以外のリソース(S3/DynamoDBなど)のIAMロールの設定をする
environment Lambda関数の環境変数と値のペアを設定する

package項目

項目名 説明 備考
include/exclude パッケージされるファイルとして含めたい/除きたいファイルを指定 ワイルドカードによる再帰的指定可能。tsconfig.jsonの同盟項目と同じ
excludeDevDependencies excludeDevDependenciesのモジュールを自動で除外するか デフォルトはtrue
artifact 自分でパッケージをする際のパッケージファイルの置き場? include/exclude設定関係なく、deploy時にパッケージファイルから除外される
individually Lambda関数単位でのパッケージを行うかどうか

functions項目

※functionsの子要素には、デプロイされるLambda関数のfunction名を記載する。下記はその子要素(functionsの孫要素)

項目名 説明 備考
handler 実行する関数。[ファイル名.exports名]形式で記載
events Lambda関数を実行するトリガーとなるイベントの種類 http(API Gateway)/s3/Alexa Skillなど
reservedConcurrency この関数を同時並行で実行できる数?
environment この関数に定義する環境変数と値のペア

resources項目

※resources要素には「Resources」-「リソース定義名」までは決め打ちになる。(「serverless.ymlのサンプル」参照)
下記は「リソース定義名」の子要素になる。(=resourcesのひ孫要素)
※Propertiesの子要素は、Typeごとに異なる。CloudFormationのテンプレートを参照。

項目名 説明 備考
Type リソースのタイプ。DynamoDB/S3など [ファイル名.exports名]形式で記載 AWS::S3::Bucketのように、CloudFormation形式で記載
Properties リソースタイプ別の詳細設定 S3ならバケット名など。(設定項目はリソースにより異なる)

Outputs項目

※Outputsの子要素には、Output項目の定義名を指定する。下記はその子要素になる。(=Outputsの孫要素)
※Outputsに定義した項目はCloudformationの「出力」に登録され、別のCloudFormationテンプレイートファイルから参照することができる。
※もちろん別のserverless.ymlファイルからも参照することが可能。(詳細はその2で記載予定)

項目名 説明 備考
Value 他の定義で参照させたいリソース、プロパティなどの情報。 Ref, Fn::GetAttなど、参照を使用して設定することが可能
Export 他の定義から参照する際に使用する名前(≒エイリアス) 「Name」プロパティに設定する
Description この定義についての説明

serverless.ymlのサンプル

app: makky12-serverless-app

# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
frameworkVersion: ">=1.0.0"

custom:  
  author : makky12  

provider:
  name: aws
  runtime: nodejs10.x  
  stage: dev
  region: ap-northeast-1
  stackName: makky12-serverless-app
  apiName: makky12-serverless-app-dev
  deploymentBucket:
    name: makky12-serverless-app-dev-bucket
    serverSideEncryption: AES256
  deploymentPrefix: makky12
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:ListBucket"
      Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ]  }
    - Effect: "Allow"
      Action:
        - "s3:PutObject"
      Resource:
        Fn::Join:
          - ""
          - - "arn:aws:s3:::"
            - "Ref" : "ServerlessDeploymentBucket"
            - "/*"

package:
  exclude:
    - exclude-dir/readmme.txt

functions:
  greeting:
    handler: handler.greeting
    events:
      # httpはAPI Gatewayがトリガになるイベント。  
      # corsはクロスオリジン制約に関する設定。
      # privateにtrueを設定すると、APIキーの指定が必須になる。(x-api-key)
      - http:
          path: users/create
          method: get
          cors: true
          private: true

  environment:
    NENGO: Reiwa

resources:
  Resources:
    makky12Bucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: makky12-bucket
    makky12Table:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: makky12Table
        AttributeDefinitions:
          - AttributeName: e-mail
            AttributeType: S
        KeySchema:
          - AttributeName: e-mail
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

Outputs:
  MyWebHookUrl:
    Description: The Url of the Custom WebHook
    Value:
      "Fn::GetAtt": [ myWebHook, Url ]
    Export:
      Name: myWebHookUrlVal

と、なんか書いてたらものすごく長くなってしまいましたので、本当はデプロイやserverless.ymlの変数仕様についても書く予定だったのですが、それはその2に書きます。