S3의 이벤트를 EventBridge로 경유해보기

S3에서 EventBridge로 이벤트를 보내는 방법에 대해 알아보겠습니다.
2023.03.27

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

안녕하세요 DA사업본부 송영진입니다.

오늘은 S3의 버켓에서 오브젝트의 생성이나 삭제로 발생하는 이벤트들을 EventBridge로 보내는 방법을 알아보겠습니다.

기존의 S3 이벤트

S3 이벤트를 어디서 사용할까요? 저는 주로 Lambda가 기동되는 트리거로 사용합니다.

다음과 같이 Lambda 함수의 트리거로 오브젝트의 생성이나 삭제, 복원 등의 이벤트를 트리거로 사용 할 수 있습니다.

이 때, 이벤트의 구성은 어떻게 될까요? 다음과 같이 간단하게 어떤 입력의 형태로 실행이 되는지 Lambda 함수의 출력으로 확인해보겠습니다.

def lambda_handler(event, context):
    print(event)
    return

test.txt라는 파일을 S3 트리거 설정이 된 버켓에 업로드 후 로그를 확인해보겠습니다.

INIT_START Runtime Version: python:3.9.v18	Runtime Version ARN: arn:aws:lambda:ap-northeast-2::runtime:edb5a058bfa782cb9cedc6d534ac8b8c193bc28e9a9879d9f5ebaaf619cd0fc0
START RequestId: 38fdc858-98d2-4443-9024-d7216a2371e3 Version: $LATEST
{
   "Records":[
      {
         "eventVersion":"2.1",
         "eventSource":"aws:s3",
         "awsRegion":"ap-northeast-2",
         "eventTime":"2023-03-27T13:10:39.266Z",
         "eventName":"ObjectCreated:Put",
         "userIdentity":{
            "principalId":"AWS:XXXXXXXXXXXXXX:botocore-session-XXXXXXXXXXXXXX"
         },
         "requestParameters":{
            "sourceIPAddress":"XXX.XXX.XXX.XXX"
         },
         "responseElements":{
            "x-amz-request-id":"XXXXXXXXXXXXXX",
            "x-amz-id-2":"XXXXXXXXXXXXXX"
         },
         "s3":{
            "s3SchemaVersion":"1.0",
            "configurationId":"99aba827-43a9-4d0f-872a-d691c8ed4dbc",
            "bucket":{
               "name":"cm-song",
               "ownerIdentity":{
                  "principalId":"XXXXXXXXXXXXXX"
               },
               "arn":"arn:aws:s3:::cm-song"
            },
            "object":{
               "key":"test.txt",
               "size":0,
               "eTag":"d41d8cd98f00b204e9800998ecf8427e",
               "sequencer":"00641C4FCF3C1F68F3"
            }
         }
      }
   ]
}
END RequestId: 38fdc858-98d2-4443-9024-d7216a2371e3
REPORT RequestId: 38fdc858-98d2-4443-9024-d7216a2371e3	Duration: 1.30 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 36 MB	Init Duration: 106.24 ms

결과는 위와 같은 JSON형식으로 출력이 됩니다.

이러한 트리거를 사용하여 파일을 S3에 업로드 했을 때 파일에 대한 전처리를 하거나, 데이터베이스 또는 데이터웨어하우스로 로드하는 ETL 처리를 만드는데 용이합니다.

단점이 무엇이냐면 위와 같은 Lambda 함수가 늘어날 때마다 이벤트 알림을 새로 설정해줘야 합니다.

EventBridge 이벤트 설정

그렇다면 S3 버켓의 이벤트를 EventBridge로 보내서 사용하는 방법은 어떻게 될까요? 알아보겠습니다.

EventBridge를 통한 이벤트를 사용하려면 S3 버켓의 설정에서 EventBridge로 알림 전송을 활성화해야합니다.

다음으로 어떤 리소스에서 오는 이벤트를 어느 타겟에게 보낼지 EventBridge에서 규칙을 작성해보겠습니다.

대상은 같은 Lambda 함수에 S3의 오브젝트가 생성되었을 때를 이벤트로 사용하겠습니다.

자 이제 똑같이 S3에 파일을 업로드 후 로그를 확인해보겠습니다.

INIT_START Runtime Version: python:3.9.v18	Runtime Version ARN: arn:aws:lambda:ap-northeast-2::runtime:edb5a058bfa782cb9cedc6d534ac8b8c193bc28e9a9879d9f5ebaaf619cd0fc0
START RequestId: b65435d7-0ed2-49e1-a2f2-52217b0be3ee Version: $LATEST
{
   "version":"0",
   "id":"174ed682-3c88-602d-7e97-6afd3a863393",
   "detail-type":"Object Created",
   "source":"aws.s3",
   "account":"XXXXXXXXXXXXXX",
   "time":"2023-03-27T14:20:28Z",
   "region":"ap-northeast-2",
   "resources":[
      "arn:aws:s3:::cm-song"
   ],
   "detail":{
      "version":"0",
      "bucket":{
         "name":"cm-song"
      },
      "object":{
         "key":"test.txt",
         "size":0,
         "etag":"d41d8cd98f00b204e9800998ecf8427e",
         "sequencer":"006421A62C3C7389FE"
      },
      "request-id":"XXXXXXXXXXXXXX",
      "requester":"XXXXXXXXXXXXXX",
      "source-ip-address":"XXX.XXX.XXX.XXX",
      "reason":"PutObject"
   }
}
END RequestId: b65435d7-0ed2-49e1-a2f2-52217b0be3ee
REPORT RequestId: b65435d7-0ed2-49e1-a2f2-52217b0be3ee	Duration: 1.30 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 36 MB	Init Duration: 108.24 ms

JSON의 형식이 약간 바뀌었지만 똑같이 Lambda의 트리거가 되었습니다!

비교

결국 하고있는 동작은 같은데 어떤 점이 다를까요?

답은 타겟과 필터링입니다. S3에서 직접 이벤트를 Lambda나 SNS 토픽에 보낼 수 있지만 이벤트의 종류를 여러 종류로 하기 위해서는 새로운 이벤트 알림을 설정해야합니다.

EventBridge의 규칙을 사용하면 위의 이벤트 패턴에서 확인 하실 수 있듯이 detail-type 항목이 리스트로 되어 있기 때문에 한 번에 여러 종류의 이벤트를 다룰 수 있고 필터링도 추가가 가능합니다.

그리고 EventBridge에서 타겟으로 설정할 수 있는 AWS 서비스가 S3의 이벤트보다 다양합니다.

API Gateway, CodePipeline, ECS 작업, Glue 워크플로, SNS 토픽, SQS 대기열, Lambda 함수, Step Functions 상태 머신 등 다양한 서비스의 트리거로서 사용할 수 있게 됩니다.

이 뿐만 아니라 무려 다른 계정의 이벤트 버스에 전송도 가능합니다. 다른 계정에서 이벤트를 받는 이벤트 버스의 설정과 룰을 사용하면 다른 계정의 이벤트를 트리거로 사용하는 방법도 가능하죠.

끝으로

오늘은 S3의 이벤트와 이벤트를 EventBridge를 경유하는 방법과 차이점에 대해 알아보았습니다.

저는 프로덕션 환경의 데이터를 스테이징 환경에서 똑같이 사용을 하기 위해서 EventBridge를 경유하는 방법을 사용하거나, Step Function의 상태 머신을 기동하기 위해 사용하곤 했는데요, 하나의 규칙으로 여러 이벤트를 관리하기 때문에 상당히 편하게 사용할 수 있었습니다. 특히 이벤트 규칙을 생성할 때, 콘솔에서 패턴이나 타겟을 다양한 항목으로 보여주기 때문에 자세히 알지 못해도 이렇게 이렇게 설정하면 되지 않을까? 하는 블록을 다루는 느낌으로 해도 쉽게 만들어져서 좋았습니다.

나중에는 CloudFormation과 같은 IaC로 다루는게 코드 관리면에서는 편해지지만 콘솔의 쉬움을 느껴보시고 넘어가시는 것도 좋은 방법이라고 생각합니다. 이 블로그가 여러분들께 도움이 되었으면 좋겠습니다 감사합니다!