はじめまして。株式会社GA technologies のService Development Division (開発部門) エンジニアの永冶といいます。 今後、この技術ブログを通して様々なことをアウトプットし、記事を閲覧する方の力に少しでもなれたらと思います。よろしくお願いします。
この記事を書いた経緯
弊社ではAWS Lambdaを
- 画像の圧縮
- Slackへの通知
- 外部サービスとの連携
などで幅広く使用しています。数多くのLambda関数を管理する上で、設定の可視化とデプロイの自動化は避けては通れません。設定の可視化とデプロイの自動化を達成するために、弊社のいくつかのプロジェクトではserverless frameworkを使用しています。
社内で運用を続けていく上で、serverless frameworkを使用する時のオススメの設定やプラグインが洗練されてきました。 この記事を読むことで、frameworkを運用する際の参考にしていただければと思います。
対象読者
- AWS Lambdaを使用している
- serverless frameworkの使用を検討している
- serverless frameworkを使い始めた
動作確認環境
バージョン
Node.js v10.10.0 Python 3.6.6 serverless 1.32.0
オススメ設定
ログの有効期間を設定しよう
serverlessのデフォルトの設定では、Lambda関数のCloudWatch Logsの有効期間は無期限です。 簡単な通知など、永久にログを保持する必要がないものなら、課金対象にもなるので有効期間を設定しておく方が良いでしょう。
設定方法
serverless.yml
にてlogRetentionInDays
を設定します。
provider: logRetentionInDays: 30
この場合、ログは30日間保持されます。
デプロイするバケットを指定しよう
serverlessのデフォルトの設定では、デプロイするステージに応じてS3バケットを作成します。
20個のアプリケーションを検証と本番のステージごとにデプロイしようものなら、40もバケットが作成されてしまい、アカウントごとのバケット数の上限緩和申請が必要になる場合があります(経験談)。
特別な理由がなければ、あらかじめS3バケットを作成しデプロイ用のバケットを設定することで、不用意にS3バケットが作成されることがなくなります。
設定方法
serverless.yml
にてdeploymentBucket
を設定します。
provider: deploymentBucket: name: serverless-deployment
これでデプロイするバケットをserverless-deployment
にできます。
同時にデプロイしておくlambdaの旧バージョン数を指定しよう
これは大きな失敗の経験から得た教訓になります。
失敗
ある日同僚から不穏な問い合わせを受けました。「AWSコンソールであなたのアカウントはコードストレージの上限 75.0 GB を超えています。と表示され、関数パッケージのアップロードができない状態になっています。。」と。
確認すると、デプロイパッケージの容量が多いLambda関数が数100バージョン分デプロイされ、容量の上限に達していました。
原因
serverless frameworkではデフォルトで、デプロイした全てのバージョンを保持するようになっています。 過去にデプロイした大量のバージョンがLambdaのコードストレージを圧迫していました。
対策
serverless frameworkでは、バージョン管理をしないという設定を、下記のようにserverless.yml
に書くことができます。
provider: versionFunctions: false
しかし、エラーがあった際のロールバックなどを考えると、最新から何世代かのバージョンを残しておくようにしておく方がいいでしょう。 プラグインserverless-prune-pluginを使用すれば、最新からいくつかのバージョンのみ保持するようにしておき、他はデプロイ時に破棄することができます。
プラグインserverless-prune-plugin
をインストールし、serverless.yml
に設定を書くだけです。
plugins: - serverless-prune-plugin
こうすることでsls prune
というコマンドを使用して、指定したバージョンのみを保持し、その他は削除することができます。
削除処理も自動化しておきたい場合はさらに、
custom: prune: automatic: true number: 3
とすれば良いです。こうすれば最新から3つのバージョンのみ保持し、残りは削除してくれます。
他にも有用な設定がないか知りたい場合は、serverless.ymlのドキュメントを見てください。 serverless.yml
オススメプラグイン
serverless-plugin-aws-alerts エラー検知
Lambda関数を作成する度に、CloudWatchアラームの設定をするのは面倒です。
プラグインserverless-plugin-aws-alerts
は、serverlessでデプロイした時に同時にアラームの設定してくれたらとても便利です。
実行エラーなどのメトリクスが閾値を超えたらSNSに通知し、SNSをサブスクライブするLambda関数でSlackに通知して、開発者に知らせるということをよくやっています。
設定方法
例としてserverless.yml
に下記のように記載します。
plugins: - serverless-plugin-aws-alerts custom: alerts: stages: # Optionally - select which stages to deploy alarms to - dev - prod topics: alarm: hoge-alerts-alarm definitions: # these defaults are merged with your definitions functionErrors: treatMissingData: notBreaching period: 300 # override period description: Lambda関数の実行に失敗しました。CloudWatchのログを確認してください。 alarms: - functionErrors
これは、
- devとprodステージで
- 300秒の期間内に
- 関数実行エラーが発生したら
- SNSトピックhoge-alerts-alarmに通知する
という設定になります。
serverless-python-requirements Pythonライブラリをデプロイ時に自動でパッケージ化
PythonでLambda関数のコードを書いている際は重宝します。requirements.txt
に必要なライブラリを記載しておきさえすれば、
このプラグインによって、自動的にライブラリがパッケージに取り込まれます。
設定方法
serverless.yml
に下記のように記載します。
plugins: - serverless-python-requirements
あとは必要なライブラリをrequirements.txt
に記載するだけです。
$ pip install requests
$ pip freeze > requirements.txt
まとめ
最後にこれまで列挙した内容をserverless.yml
にまとめました。
service: hoge # NOTE: update this with your service name provider: name: aws runtime: python3.6 stage: dev region: ap-northeast-1 logRetentionInDays: 7 deploymentBucket: name: serverless-deployment # NOTE: update this with your deployment bucket name plugins: - serverless-plugin-aws-alerts - serverless-python-requirements - serverless-prune-plugin functions: hello: handler: handler.hello custom: alerts: stages: # Optionally - select which stages to deploy alarms to - dev topics: alarm: hoge-alerts-alarm # NOTE: update this with your topic name definitions: functionErrors: treatMissingData: notBreaching period: 300 # override period description: Lambda関数の実行に失敗しました。CloudWatchのログを確認してください。 alarms: - functionErrors prune: automatic: true # $LATESTから5バージョンのみ保持する number: 5
serverless frameworkとプラグインをうまく使用することで、より良い環境が用意できます。 これからもserverless frameworkをキャッチアップしていき、バージョンアップ情報や良いプラグイン情報を得たら積極的にシェアしていきたいと思います。