155
121

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Serverless Frameworkを本番運用する際にやっておいたほうが良い事

Last updated at Posted at 2017-11-30

この記事の概要

Serverless Framework を本番環境で運用する際にやっておいたほうが良い設定を紹介させて頂きます。

前提条件

以下の要件で運用しているという前提でお話させて頂きます。

  • AWS Lambdaを利用している事
  • Node.js 6.10のランタイムを使用している事
  • Serverless Framework のバージョンは 1.24.1 を利用している事(この記事を書いている 2017-11月時点での最新版)

なお、この記事を書くにあたって開発したのはデータベースにDynamoDBを利用したREST APIです。

CloudWatch Logsを出力するように設定しておく

Serverless Framework はLambdaの実行結果を CloudWatch Logs にログとして出力します。

しかし、私は開発中ログが出力されていない事がありました。(どういう状況でそうなったかは今でも不明です。)

もしログ出力がされていない場合は serverless.yml に以下の記述を追加しましょう。

serverless.yml
provider:
  name: aws
  runtime: nodejs6.10
  iamRoleStatements:
    - Effect: Allow
      Action:
        - logs:CreateLogGroup
        - logs:CreateLogStream
        - logs:PutLogEvents
      Resource:
        - "*"

IAMロールに CloudWatch Logsへの書き込み権限を与えています。

詳しくは CloudWatch Logs の権限リファレンス を参照して下さい。

先程は書きましたが通常はログ出力は行われるハズです。
この手順に関してはログ出力がされていない場合のみ行えばOKです。

以下のようにログGroupが作成されていればログ出力が行われています。

logs.png

ログが出力されていないと、問題が起こった際の調査が非常に困難になるので、必ずログが出力されている事を確認するようにしましょう。

コールドスタート対策

Serverless Frameworkで行うLambdaのコールドスタート対策 という記事を書かせて頂きました。

こちらの記事 に載っているようにProvisioned Concurrencyを設定する事で実行可能なコンテナが消えないように設定を行います。

CloudWatch Logsの有効期限を設定する

Serverless Framework が作成するCloudWatch Logsはdefaultでは有効期限なし(つまり無尽蔵に保存される)です。

放っておくと料金がどんどん高くなってしまうので、こちらも対策を行っておいたほうが良いでしょう。

こちら に載っているように、標準で作成される /aws/lambda/{service_name}-{stage}-{function_name} のログGroupの定義を上書きする事で対応を行います。

下記に設定例を記載します。

関数名が refreshToken だった場合は RefreshTokenLogGroup というResourcesを定義する事で上書きが行えます。 RetentionInDays: "30" は30日間保存する設定です。

WarmUpPluginLogGroup に関しては コールドスタート対策で入れた serverless-plugin-warmup を導入すると自動で作成される関数です。

こちらの場合は1日分くらいのログが残っていれば十分なので RetentionInDays: "1" としてあります。

serverless.yml
functions:
  refreshToken:
    handler: build/functions/token.refreshToken
    warmup: true
    events:
      - http:
          path: tokens/refresh
          method: post
          cors: true

resources:
  Resources:
    RefreshTokenLogGroup:
      Properties:
        RetentionInDays: "30"
    WarmUpPluginLogGroup:
      Properties:
        RetentionInDays: "1"

2018-03-28 追記

Serverless Frameworkv1.26.0以降はより簡潔にCloudWatch Logsの有効期限を設定出来るようになりました。

(参考)Serverless Framework v1.26.0リリースノート

以下のように provider セクションに logRetentionInDays を設定するだけでOKです。

下記の例では10日で設定しています。

serverless.yml
provider:
  logRetentionInDays: 10

全ての関数が同じ保存日数であれば問題はないですが、個別の関数毎に有効期限を設定したいという場合はやはりLogGroupのリソースを上書きしてあげる必要があります。

総容量が原因でデプロイ出来なくなる事を防ぐ

AWS Lambdaのコードストレージの総容量は75GBが最大でこれ以上の容量になるとデプロイ自体が出来なくなります。

しばらく使っていると下記の画像のように容量がどんどん増えていきます。

before-prune.png

これはデプロイ毎に古い関数のバージョンもストレージに残ってしまう為、起こっている現象です。

容量不足になる前に serverless-prune-plugin を利用して対策を行いましょう。

インストール方法は serverless-prune-plugin の通りに進めれば問題ありません。

私の場合は yarn を利用して yarn add serverless-prune-plugin --dev でインストールを行いました。

インストール完了後 serverless.yml に以下のように記述します。

serverless.yml
plugins:
  - serverless-prune-plugin

custom:
  prune:
    automatic: true
    number: 3

automatic はPluginをデプロイ時に自動で動作させる為の設定で、number: 3 は直近の3つのバージョンまでコードストレージに残すという意味です。

このあたりは各自で調整すると良いでしょう。

設定完了後、 serverless deploy -v を実行すると以下のようにデプロイ時のログでPluginが動作している事が確認出来るかと思います。

// 中略
Serverless: Prune: Running post-deployment pruning
Serverless: Prune: Querying for deployed versions
Serverless: Prune: authorizer-dev-findClient has 70 additional versions published and 0 aliases, 67 versions selected for deletion
Serverless: Prune: Deleting authorizer-dev-findClient v67...
Serverless: Prune: Deleting authorizer-dev-findClient v66...
Serverless: Prune: Deleting authorizer-dev-findClient v65...
Serverless: Prune: Deleting authorizer-dev-findClient v64...
Serverless: Prune: Deleting authorizer-dev-findClient v63...
Serverless: Prune: Deleting authorizer-dev-findClient v62...
Serverless: Prune: Deleting authorizer-dev-findClient v61...
Serverless: Prune: Deleting authorizer-dev-findClient v60...

デプロイ完了後にコードストレージの容量を確認すると以下のように容量が減っている事が確認出来るかと思います。

after-prune.png

監視

Serverlessだからと言って監視が不要になるという訳ではありません。

問題が起きた際には素早く検知出来る仕組みを構築する事が必要です。

CloudWatchのカスタムメトリクスで特定のエラーコードが発生した際に Slack に通知するような仕組みを作成すると良いでしょう。

サンプルを用意出来れば良かったのですが、時間がなくサンプルの用意が間に合いませんでした。。。
サンプルが完成次第この記事を更新します。

それまでは参考になりそうな記事を記載させて頂きます。

まとめ

記事の内容は以上になります。

今後も運用を続けていきますので新たに有効な情報が分かったら、発信して行きたいと思います。

他にも本番時に有効な設定等がありましたら、コメント等で教えて頂けると幸いです。

最後まで読んで頂きありがとうございました。

155
121
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
155
121

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?