serverless-plugin-log-subscriptionでサブスクリプションフィルターを一括設定する

2022.08.04

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

大阪オフィスの小倉です。

Serverless Frameworkのプラグインであるserverless-plugin-log-subscriptionを導入して、
サブスクリプションフィルターの管理がとても簡単になったので紹介します。

概要

Serverless Frameworkを使ってLambdaのCloudWatch Logsロググループに
サブスクリプションフィルターを設定する場合、
基本的には各ロググループに対して一つずつ設定を記述する必要があります。

serverless-plugin-log-subscriptionを使うことで、YAMLテンプレート内で管理する全てのLambdaに対して一括でサブスクリプションフィルターを設定することが出来ます。

やってみる

今回は以下の環境で検証しました。

環境 バージョン
Serverless Framework 3.21.0
serverless-plugin-log-subscription 2.1.2

構成

今回の構成は以下の通りです。

アプリケーションLambdaがCloudWatchLogsに出力するログの中で、特定の文字を見つけたら、
サブスクリプションフィルターの機能で、通知実行用のLambda関数を呼び出します。

サブスクリプションフィルターを動作させるには、

  1. サブスクリプションフィルターの作成
  2. CloudWatchLogsからのLambda呼び出しを許可するリソースベースポリシーの作成

が必要となり、この部分をプラグインが支援してくれます。

※通知実行用Lambda−>SNS−>メール送信の部分については以下のブログを参照ください。

実装

ログの中に「ERROR」という文字列を見つけたらサブスクリプションフィルターが動く例です。

フィルターを設定したいLambdaに対して、logSuscription: trueを指定します。 通知実行用LambdaのArnは、 destinationArn に指定します。

service: log-subscription-project
frameworkVersion: '3'
plugins:
  - serverless-plugin-log-subscription

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

custom:
  logSubscription:
    destinationArn: <通知実行用LambdaのArn>
    filterPattern: 'ERROR'  # ログの中にERRORという文字を見つけたら発動

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          path: /
          method: get
    logSubscription: true  # サブスクリプションフィルターの有効化

テンプレートに多数のLambdaが定義されている場合、custom配下にenabled: trueを指定することで一括設定できます。
各Lambdaの定義でlogSubscription: falseを指定すると、個別にサブスクリプションフィルターを無効化出来ます。

custom:
  logSubscription:
    destinationArn: <通知実行用LambdaのArn>
    filterPattern: 'ERROR'  # ログの中にERRORという文字を見つけたら発動
    enabled: true  # サブスクリプションフィルターの一括有効化

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          path: /
          method: get
  world:
    handler: handler.hello
    events:
      - httpApi:
          path: /world
          method: get
    logSubscription: false  # 例外的にこのLambdaだけサブスクリプションフィルターを作らない
  hoge:
    handler: handler.hello
    events:
      - httpApi:
          path: /hoge
          method: get

Lambdaの数が多いと、通知実行用Lambdaに対して、リソースベースポリシーが大量に自動作成されてしまい、 Lambda関数リソースベースポリシーのサイズ上限(20KB)を超えてしまうおそれがあります。
この場合は以下のようなエラーになります。

The final policy size (20560) is bigger than the limit (20480).

このような場合は、予め自前で複数のロググループに対応できるようなポリシーを用意しておき、

custom:
  logSubscription:
    addLambdaPermission: false # リソースベースポリシーの自動生成を停止

とすることで、プラグインによるリソースベースポリシーの自動生成を停止することが出来ます。

まとめ

Serverless Frameworkを使いながらサブスクリプションフィルターを設定していると、テンプレートの記述量がどうしても増えてしまったり、
Lambda関数を追加した際にサブスクリプションフィルターを追加し忘れる事があって困っていました。

プラグインを導入することで設定が自動化され、テンプレートの記述量も大幅に削減することが出来たので、
同じ様な悩みがある方はぜひ使ってみてください。

参考資料