のべラボ.blog

Tech Blog | AWS や サーバーレスやコンテナ などなど

Amazon EventBridge で新たに追加されたフィルターの機能を試してみる

Amazon EventBridge のルールで指定できるフィルター機能が拡張され、下記の評価方法が利用できるようになりました。

  • suffix filter (拡張子を指定したフィルター)
  • equals-ignore-case (大文字小文字を区別しないマッチング)
  • OR matching (複数のフィールドの条件で1つでもtrueであればよい)

aws.amazon.com

地味な機能拡張と思われるかもしれませんが、以前、拡張子を指定したフィルターができなくて困ったことがあったので、個人的には嬉しく感じています!

今回は、この suffix filter (拡張子を指定したフィルター)の機能を試していきます。

なお、この記事の内容は 2022 年 11月 20 日時点で確認したものになります。


簡単にこの機能を試したいだけなので、次のような構成を作ることにしました。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20221120/20221120171954.png

Amazon S3 バケットから Amazon EventBridge への通知については、次のドキュメントも参考にしてみて下さい。

aws.amazon.com


今回は、EventBridge のターゲットになる Lambda 関数は、Python を使う前提です。

上図の構成を作成する AWS SAM テンプレートは、次のようになります。

S3 バケット名はパラメータにしていますが EventBridge ルール名、Lambda 関数名は任意のものに変更して下さい。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  Demo of EventBridge suffix filter rule 
Globals:
  Function:
    Timeout: 3
Parameters:
  DemoBucketName:
    Type: String
    Default: "tnobe-test-suffix-filter-bucket"
    Description: "Bucket name for demo of EventBridge suffix filter rule"
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref DemoBucketName
      NotificationConfiguration:
        EventBridgeConfiguration:
          EventBridgeEnabled: true
  EventPrinterFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: "test-suffix-filter-function"
      CodeUri: event_printer/
      Handler: app.lambda_handler
      Runtime: python3.7
  SuffixFilterRule: 
    Type: AWS::Events::Rule
    Properties: 
      Name: "test-suffix-filter-rule"
      Description: " .jpg or .jpeg files only"
      EventPattern: 
        source: 
          - "aws.s3"
        detail-type:
          - "Object Created"  
        detail: 
          bucket:
             name: 
               - !Ref DemoBucketName
          object:
            key:
              - suffix: ".jpg"
              - suffix: ".jpeg"
      State: "ENABLED"
      Targets: 
        - 
          Arn: 
            Fn::GetAtt: 
              - "EventPrinterFunction"
              - "Arn"
          Id: "Target1"
  PermissionForEventsToInvokeLambda: 
    Type: AWS::Lambda::Permission
    Properties: 
      FunctionName: 
        Ref: "EventPrinterFunction"
      Action: "lambda:InvokeFunction"
      Principal: "events.amazonaws.com"
      SourceArn: 
        Fn::GetAtt: 
          - "SuffixFilterRule"
          - "Arn"      
Outputs:
  EventPrinterFunction:
    Description: "EventPrinter Lambda Function ARN"
    Value: !GetAtt EventPrinterFunction.Arn
  EventPrinterFunctionIamRole:
    Description: "Implicit IAM Role created for EventPrinterFunction "
    Value: !GetAtt EventPrinterFunctionRole.Arn

今回は AWS SAM を使用して Amazon EventBridge のルールを作成していますが、もちろん AWS マネジメントコンソールから作成することもできます。

AWS マネジメントコンソールから作成する場合は、ルールのフィルター設定を JSON で指定する必要があるので、参考までに JSON での拡張子フィルター例を次に掲載しておきます。

{
  "source": ["aws.s3"],
  "detail-type": ["Object Created"],
  "detail": {
    "bucket": {
      "name": ["tnobe-test-suffix-filter-bucket"]
    },
    "object": {
      "key": [ {
        "suffix": ".jpg"
      }, {
        "suffix": ".jpeg"
      }]
    }
  }
}

また、この AWS SAM テンプレートでは、Lambda 関数のコードのファイルが event_printer/ フォルダにあることを指定しています。

よって、テンプレートが存在する場所の event_printer フォルダに app.py のファイルを作成します。

コードの内容は、受け取った Event をそのまま CloudWatch Logs に出力するだけの非常にシンプルなものです。

import json

def lambda_handler(event, context):

    print(event)
    return {
        "statusCode": 200,
        "body": "hello"
    }

これで環境作成の準備ができたので、AWS SAM CLI でデプロイを行います。

sam build
sam deploy --guided

sam deploy --guided を実行すると、対話式で入力が求めらるので、入力します。 (基本的にS3 バケットの名前は入力が必要ですが、それ以外についてはデフォルトの値でかまいません。)

デプロイが完了すると、次のようなメッセージが表示されます。

Successfully created/updated stack - (スタック名) in ap-northeast-1

これで環境は作成できたので、作成した S3バケット.jpg の拡張子をもつファイルを用意して、アップロードしてみましょう。

下記は例です。

BUCKET_NAME="tnobe-test-suffix-filter-bucket"
aws s3 cp cat.jpg s3://${BUCKET_NAME}

この後、作成した Lamnda関数の CloudWatch Logs のログを見てみます。すると、次の例のようなログが出力されます。

START RequestId: b569974b-28d3-4416-886b-4dc9699d0d7e Version: $LATEST
{'version': '0', 'id': 'c95b6b28-0376-cd78-ecf2-d0d100264f3d', 'detail-type': 'Object Created', 'source': 'aws.s3', 'account': '330174381929', 'time': '2022-11-20T04:13:37Z', 'region': 'ap-northeast-1', 'resources': ['arn:aws:s3:::tnobe-test-suffix-filter-bucket'], 'detail': {'version': '0', 'bucket': {'name': 'tnobe-test-suffix-filter-bucket'}, 'object': {'key': 'cat.jpg', 'size': 480853, 'etag': 'b9e3d3da605744062c9a84561a425f47', 'sequencer': '006379A971A6A2DC0E'}, 'request-id': 'RD147W3MYT7D1075', 'requester': '123412341234', 'source-ip-address': '54.238.13.87', 'reason': 'PutObject'}}
END RequestId: b569974b-28d3-4416-886b-4dc9699d0d7e
REPORT RequestId: b569974b-28d3-4416-886b-4dc9699d0d7e  Duration: 8.76 ms   Billed Duration: 9 ms   Memory Size: 128 MB Max Memory Used: 37 MB  

ログが出力されたことで、まず EventBridge の拡張子のフィルターで評価され、Lambda 関数が実行されたことがわかります。

またログ内容から、自分が指定したファイルのアップロードによるイベントでこのLambda 関数が実行されたことがわかります。

他にも、拡張子が .jpeg のものや、フィルター条件にマッチしないもの (.png や .txt など)も試してみて下さい。

aws s3 cp cat.jpeg s3://${BUCKET_NAME}
aws s3 cp dog.png s3://${BUCKET_NAME}
aws s3 cp test.txt s3://${BUCKET_NAME}

上記の例だと、cat.jpeg では、Lambda 関数は実行されますが、それ以外については実行されないことがわかります。

今回は非常にシンプルな構成で試しましたが、このように Amazon EventBridgeの拡張子によるフィルタリングは、S3 バケットのイベントを扱う時に便利ではないか!!と感じます。

/* -----codeの行番号----- */