LoginSignup
11
8

More than 5 years have passed since last update.

CloudWatch Logsサブスクリプションフィルタを使ってLambdaを動かす

Posted at

subscriptionFilter

CloudWatch Logsに入ってきたデータをイベントドリブンに処理が可能なものです。
各ロググループに1つのみ適応可能という制限があります

subscriptionFilterを使ってLambdaを起動する方法を説明します。

なお、subscriptionFilterの設定はマネコンではできないはずです

設定

前提として、動かすLambdaはできているものとします。
設定はCFnを用いて行います

対象のLambda名: sample-lambda
対象のロググループ名: sample-log

nested-template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  SourceLogGroup:
    Description: "CWL log group name"
    Type: "String"
  LambdaFunctionName:
    Description: "Lambda function name"
    Type: "String"
  filterPattern:
    Description: "CWL filter pattern"
    Type: "String"
Resources:
  subscriptionFilter:
    Type: "AWS::Logs::SubscriptionFilter"
    Properties:
      LogGroupName: !Ref SourceLogGroup
      FilterPattern: !Ref filterPattern
      DestinationArn: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunctionName}"

設定を行うのは上記のテンプレートのとおりです。

subscription-filter-root-stack.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: "root stack for cloudwatch logs subscription filter template."
Mappings:
  ResourceMapping:
    LambdaFunction:
      name: "sample-lambda"
    clpudwatchLogsFilterPattern:
      all: ""
      error: "error"
Resources:
  CWLSubscriptionFilterStack:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      TemplateURL: <nested-template.yaml への相対パス>
      Parameters:
        SourceLogGroup: "sample-log"
        LambdaFunctionName: !FindInMap [ ResourceMapping, LambdaFunction, name ]
        filterPattern: !FindInMap [ ResourceMapping, clpudwatchLogsFilterPattern, default ]

必要なロググループ分リソースを追加していけば大丈夫です。

デプロイ

aws cli を用いてデプロイします。設定は終わっているものとします。
ネストしたテンプレートはS3に上がっている必要があるので先にpackage化します。

command
aws cloudformation package \
    --template-file ./ubscription-filter-root-stack.yaml \ # 2つ目に書いたテンプレートへのパス
    --s3-bucket ${S3_BUCKET_NAME} \ # テンプレートを格納するS3(CWLと同一リージョンのS3を使うこと)
    --s3-prefix ${REPOSITORY_NAME} \ # S3に格納する際のプレフィックスを指定
    --output-template-file ./bscription-filter-root-stack-package.yaml  # package化してデプロイに使用するテンプレートの出力先

デプロイ

command
aws cloudformation deploy \
    --s3-bucket ${S3_BUCKET_NAME} \ # テンプレートを格納するS3
    --template-file ./bscription-filter-root-stack-package.yaml \  # package化してデプロイに使用するテンプレート
    --stack-name ${STACK_NAME} \ # デプロイするCFnスタックの名称
    --capabilities CAPABILITY_NAMED_IAM \ # 固定値だと思っていいです
    --role-arn ${ROLE_ARN} # CFnを動かす権限を持ったロールを指定

注意

CWLのsubscriptionFilterからLambdaを動かす際にはLambdaに特殊な権限が必要です。
権限が無い状態でこのCFnを動かすとエラーでロールバックします
権限の設定はCLIで行います

command
aws lambda add-permission \
    --function-name "sample-lambda" \
    --statement-id "sample-log-sample-lambda" \
    --principal "logs.<region>.amazonaws.com" \
    --action "lambda:InvokeFunction" \
    --source-arn "arn:aws:logs:<region>:<account-id>:log-group:sample-log:*" \
    --source-account "<account-id>"

<>で囲われてる部分は直してください。

なお、上記commandを打っていない状態であれば下記のCFnを適応することでデプロイが可能

template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  SourceLogGroup:
    Description: "CWL log group name"
    Type: "String"
  LambdaFunctionName:
    Type: "String"
  filterPattern:
    Type: "String"
Resources:
  subscriptionFilter:
    DependsOn:
      - LambdaInvokePermission
    Type: "AWS::Logs::SubscriptionFilter"
    Properties:
      LogGroupName: !Ref SourceLogGroup
      FilterPattern: !Ref filterPattern
      DestinationArn: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunctionName}"
  LambdaInvokePermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      FunctionName: !Ref LambdaFunctionName
      Action: "lambda:InvokeFunction"
      Principal: !Sub "logs.amazonaws.com"
      SourceAccount: !Ref AWS::AccountId
      SourceArn: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${SourceLogGroup}:*"

上記テンプレートはCLIを使ってパーミッション入っていると逆に落ちます。

11
8
1

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
11
8