Tech

AWS EventBridge를 활용한 업무 자동화

2022. 05. 11

안녕하세요, 화해 데브옵스팀 장영석입니다. EventBridge를 활용한 자동화

 

AWS가 제공하는 서비스들은 대부분 모니터링 및 로깅을 제공합니다. 하지만 AWS 리소스에서 CloudWatch로 로그를 수집할 경우, 보관 주기를 CloudWatch의 AWS 콘솔이나 CLI를 사용하여 별도로 설정해줘야 하는 번거로움이 있습니다. 예를 들어 API Gateway stage의 로깅 설정 시 보관 주기 설정 기능이 없어 CloudWatch log group에서 재설정을 해야 합니다. 또 다른 예시로 CodeBuild 작업의 진행상황을 받아보려 해도 AWS 콘솔이나 CLI를 통한 알림 설정을 제공하지 않습니다.

 

이러한 불편함을 해소하기 위한 업무 자동화 방법 중 하나로 EventBridge를 소개합니다. 이번 글에서는 EventBridge의 여러 역할 중 AWS 서비스 이벤트 데이터 전송에 대해서 다루려 합니다.

 

EventBridge는 AWS 서비스 이벤트를 사용하여 이벤트 기반 애플리케이션을 대규모로 손쉽게 구축할 수 있는 서버리스 이벤트 버스로, 이벤트 소스의 실시간 이벤트 스트림을 원하는 대상으로 전송하는 역할을 합니다. 또한 이벤트 패턴을 기반으로 Rule을 설정하여 데이터를 필터링하고 전송할 대상을 선택할 수 있어 이벤트 생산자와 소비자의 분리가 가능합니다.

 

 

 

EventBridge의 AWS 서비스 이벤트 처리 방식

 

여러 이벤트 소스 중 AWS Service는 EventBridge의 Default EventBus를 사용하며 수많은 이벤트를 전송합니다. 현재 EventBridge가 지원하는 AWS 서비스 목록은 공식 문서에서 확인할 수 있습니다.

 

Default EventBus에 전송된 이벤트는 Rule을 통해 사용자가 설정한 이벤트 패턴을 기반으로 필터링되고 필요한 대상에게 전달됩니다. 대상은 다양한 방식으로 설정할 수 있습니다. 예를 들어 이벤트 데이터를 파싱 하여 원하는 메시지 형태로 Slack에 전송하는 AWS Lambda Function을 사용할 수 있습니다. 또는 SNS Topic으로 이벤트를 전송하고 해당 Topic을 Subscribe 하는 대상들이 이벤트를 처리하도록 구성할 수도 있습니다.

 

 

EventBridge를 사용해 이벤트를 처리하는 방식 예시

EventBridge를 사용해 이벤트를 처리하는 방식 예시

 

 

 

Rule을 사용하여 필요한 이벤트 데이터 필터링하기

 

Rule의 역할은 이벤트 데이터를 필터링하고 특정 대상에게 전달하는 것입니다. 그중 필터링에 대해서 얘기해보겠습니다.

 

대부분의 AWS Service 이벤트는 EventBridge의 Default EventBus에 JSON 형태의 콘텐츠를 전달합니다. Rule 작성 시 이벤트 패턴을 정의하여 이와 일치하는 데이터를 대상에게 전달할 수 있습니다. 이벤트 패턴에 작성하지 않은 필드는 일치 여부를 판단하지 않습니다.

 

 


 

단순한 설정이라도 사용자가 수동으로 설정해야 한다면 잘못된 값을 사용하거나 아예 작업 자체를 놓칠 가능성이 매우 큽니다. 이러한 상황을 개선한 몇 가지 자동화 사례를 소개해보겠습니다.

 

 

CodeBuild 작업 결과를 슬랙 채널에 전송하기

 

CodeBuild 프로젝트에서 빌드를 생성한 후 상태 변화를 발송하는 이벤트인 CodeBuild State Change Event를 특정 패턴과 일치하는 경우에만 대상으로 전송하는 예제를 만들어보겠습니다.

 

필터링 조건은 아래와 같습니다.

  1. 상태가 SUCCEEDED | FAILED | STOPPED인 경우
  2. CodeBuild 프로젝트 이름이 test-codebuild-project인 경우

이제 AWS Console을 사용해 Rule을 등록해보겠습니다.

 

 

Rule 생성

AWS Console → Amazon EventBridge → Events → Rules → Create rule 버튼을 클릭해 새로운 Rule을 생성합니다.

 

 

Rule 생성 화면

 

 

패턴 정의

패턴 정의 섹션에서 필요한 항목을 선택한 결과로 생성된 이벤트 패턴을 확인합니다.

 

이벤트 패턴을 직접 작성할 수도 있지만 대부분의 AWS service의 경우 기본으로 제공하는 이벤트 패턴을 선택할 수 있습니다. 아래 그림처럼 CodeBuild 이벤트 소스와 CodeBuild Build State Change 이벤트 타입을 선택합니다. Specific states는 다중 선택이 가능하므로 알림이 필요한 상태를 모두 선택합니다.

 

 

이벤트 소스 선택 화면

이벤트 소스 선택 화면

 

 

이벤트 패턴 정의 화면

이벤트 패턴 정의 화면

 

 

선택한 항목을 기반으로 이벤트 패턴이 정상적으로 생성되었는지 확인합니다. 자동 생성된 이벤트 패턴에서 build-status 값이 세 가지 상태를 포함한 리스트인 것을 확인할 수 있습니다. 세 가지 상태 중 하나라면 해당 이벤트가 일치한다고 판단합니다.


{
  ...
  "detail": {
    "build-status": ["SUCCEEDED", "FAILED", "STOPPED"]  # 세 가지 상태 중 하나만 일치한다면 통과
  }
  ...
}

아래 그림처럼 원하는 이벤트 샘플을 미리 확인할 수도 있습니다.

 

 

샘플 이벤트 조회 화면

샘플 이벤트 조회 화면

 

 

아래 샘플을 참고하여 이벤트 패턴에 사용할 수 있는 필드를 확인할 수 있습니다.


# 샘플 이벤트
{
  "version": "0",
  "id": "bfdc1220-60ff-44ad-bfa7-3b6e6ba3b2d0",
  "detail-type": "CodeBuild Build State Change",
  "source": "aws.codebuild",
  "account": "123456789012",
  "time": "2017-07-12T00:42:28Z",
  "region": "us-east-1",
  "resources": ["arn:aws:codebuild:us-east-1:123456789012:build/SampleProjectName:ed6aa685-0d76-41da-a7f5-6d8760f41f55"],
  "detail": {
    "build-status": "SUCCEEDED",
    "project-name": "SampleProjectName",
    "build-id": "arn:aws:codebuild:us-east-1:123456789012:build/SampleProjectName:ed6aa685-0d76-41da-a7f5-6d8760f41f55",
    "current-phase": "COMPLETED",
    "current-phase-context": "[]",
    "version": "1"
  }
}

지금은 프로젝트 이름이 필요하니 detail.project-name을 사용하여 아래와 같이 이벤트 패턴에 추가합니다.


{
  "source": "aws.codebuild",
  "detail-type": "CodeBuild Build State Change",
  "detail": {
    "build-status": ["SUCCEEDED", "FAILED", "STOPPED"],
    "project-name": "test-codebuild-project"  # 프로젝트 이름 패턴 추가
  }
}

완성된 패턴을 콘솔의 이벤트 패턴 항목에서 Edit pattern 버튼을 클릭하여 수정합니다.

 

 

대상 설정

Rule을 통과한 이벤트가 전달될 대상을 선택합니다. 대상은 다중 선택이 가능합니다.

 

 

대상 설정 화면

대상 설정 화면

 

 

슬랙에 이벤트를 전송하기 위해 생성해둔 lambda 함수를 대상으로 선택합니다.

 

원하는 대상을 선택한 후 Configure input 옵션을 선택하여 이벤트 콘텐츠를 원하는 형태로 대상에게 전달할 수 있습니다.

  • Configure input 옵션 설명
    • Matched events – 전달된 이벤트 값을 그대로 대상에게 전달
    • Part of the matched event – 전달된 이벤트 값 중 일부만을 선택해서 대상에게 전달
      • 예시) $.detail, $.source – detail과 source 키 항목만을 대상에게 전달
    • Constant (JSON text) – 전달된 이벤트 값을 무시하고 새로 설정한 값을 대상에게 전달
    • Input transformer – 전달된 이벤트 값을 원하는 형태로 변환
      • 보통 사람이 읽을 수 있는 형태로 전달할 때 사용합니다. 예를 들면 최종 대상이 이메일 발송인 경우 포함될 문장을 생성하는 형태. 자세한 내용은 AWS 공식 블로그 문서 참고

CodeBuild 서비스에서 생성된 값을 그대로 대상에게 전달하는 Matched events를 선택하고 하단의 Create 버튼을 통해 Rule을 생성합니다.

 

이제 Rule 작업이 완료되었습니다. Rule 상세화면의 Monitoring 탭에서 이벤트 패턴과 일치하는 케이스의 발생 지표를 확인할 수 있습니다.

 

 

Rule 발생지표 모니터링 화면

Rule 발생지표 모니터링 화면

 

 


 

API Gateway 로깅 활성화 및 log group 보관 주기 설정 자동화

 

AWS managed 서비스는 각각의 로깅 방식을 제공하고 대부분 Cloudwatch logs를 통해 지원합니다. API Gateway도 마찬가지로 AWS 콘솔에서 활성화하여 실행 로그와 액세스 로그를 기록할 수 있습니다. 하지만 로그 보관 주기 설정은 API Gateway 서비스의 자체 기능만으로는 불가능합니다. Cloudwatch logs 콘솔에서 해당 log group의 보관 주기를 직접 설정하거나 CLI를 사용하는 등의 추가 작업이 필요합니다.

 

API Gateway 로그 설정 방법과 커스텀 액세스 로그 포맷 구성을 위한 필드에는 무엇이 있는지 알아보고, Stage를 새로 생성할 때 로그 활성화 및 보관 주기 설정을 자동화하기 위한 EventBridge를 구성해보겠습니다.

 

 

API Gateway 로깅 활성화

로그 활성화는 API Gateway → API → Stage → Logs/Tracing 탭에서 가능하며 CloudWatch Settings 메뉴에서 실행 로그를, Custom Access Logging 메뉴에서 액세스 로그를 설정할 수 있습니다.

 

CloudWatch Settings

실행 로그에서는 오류 또는 요청 또는 응답 파라미터나 페이로드 데이터, 사용량 계획이 활성화되는지 여부 등의 정보가 포함되어 있습니다. 환경이나 목적별로 필요한 옵션들을 활성화하여 관리합니다.

 

 

실행 로그 설정 예시

실행 로그 설정 예시

 

 

 \Option  Value  Description
 Enable CloudWatch Logs  true  execution 로그 기록을 활성화
 Log level  Info  기록될 로그 레벨 (Info | Error)
 Log full requests/response data  true  요청/응답의 바디 데이터 기록 활성화
 Enable Detailed CloudWatch Metrics  true  metric 데이터 기록 활성화

 

 

Custom Access Logging

액세스 로그를 활성화하면 클라이언트 정보나 접근 경로, 응답 상태 코드, 지연시간 등의 다양한 정보를 조회할 수 있습니다. 제공되는 필드를 조합하여 커스텀 로그 포맷 설정도 가능합니다.

 

 

커스텀 액세스 로그 포맷 설정 예시

커스텀 액세스 로그 포맷 설정 예시

 

 

액세스 로그 저장소는 Cloudwatch와 Kinesis가 가능하나 이번 예시에서는 Cloudwatch를 사용합니다.

커스텀 로그 포맷은 아래와 같이 미리 제공되는 필드들을 값으로 사용할 수 있으며 키값은 자유롭게 설정 가능합니다.


{
  "requestId":"$context.requestId",
  "ip": "$context.identity.sourceIp",
  "requestTime":"$context.requestTime",
  "httpMethod":"$context.httpMethod",
  "resourcePath":"$context.resourcePath",
  "status":"$context.status",
  "protocol":"$context.protocol",
  "responseLength":"$context.responseLength",
  "integrationStatus":"$context.integrationStatus",
  "integrationLatency":"$context.integration.latency",
  "userAgent":"$context.identity.userAgent"
}

위 예시에서 사용되는 필드의 설명은 아래와 같습니다. 모든 필드에 대한 설명은 공식 문서를 참고합니다.

 

Key Value Description

requestId

$context.requestId

API Gateway가 API 요청에 할당하는 ID

ip

$context.identity.sourceIp

API Gateway 요청자 IP 주소

userAgent

$context.identity.userAgent

요청 User-Agent 헤더

 requestTime

$context.requestTime

CLF 형식의 요청 시간
(dd/MMM/yyyy:HH:mm:ss +-hhmm)

httpMethod

$context.httpMethod

요청 메서드 타입. DELETE, GET, HEAD,
OPTIONS, PATCH, POST, PUT

path

$context.path

요청 경로

resourcePath

$context.resourcePath

리소스에 대한 경로. 예를 들어
https://{rest-api-id}.execute-api.{region}.amazonaws.com/
{stage}/root/child의 요청 URI의 경우,
$context.resourcePath 값은 /root/child

stage

$context.stage

API 요청 stage 이름

status

$context.status

메서드 응답 상태 코드

protocol

$context.protocol

요청 프로토콜(예: HTTP/1.1)

responseLength

$context.responseLength

응답 페이로드 길이

responseLatency

$context.responseLatency

응답 지연 시간(ms)

integrationStatus

$context.integrationStatus

integration endpoint 응답 상태 코드

integrationLatency

$context.integration.latency

integration endpoint 에서 gateway 요청을 처리한 시간

 

 

CloudWatch log group 보관 주기 설정

로그 활성화 시 사용되는 execution, access log의 Cloudwatch log group의 보관 주기는 콘솔이나 AWS CLI를 통해 직접 수정해야 합니다.

 

AWS Cloudwatch Console 사용

CloudWatch → Log groups → Log group 선택 → Actions → Edit retention setting 진입하여 원하는 보관 주기를 설정합니다.

 

 

CloudWatch log group 보관주기 설정 예시

CloudWatch log group 보관주기 설정 예시

 

 

자동화 설계

먼저 API Gateway 로그 활성화 이벤트를 파악해야 합니다. Stage 생성 시점에 lambda 함수를 사용하여 CloudWatch log group을 생성 후 로그 활성화 작업을 해보겠습니다.

 

 

API Gateway 이벤트 발생시 로그 활성화 및 보관주기 설정 자동화 과정

API Gateway 이벤트 발생시 로그 활성화 및 보관주기 설정 자동화 과정

 

 

API Gateway의 Stage가 생성되는 시점을 파악하기 위한 이벤트는 CreateStage 또는 CreateDeployment입니다.

 

로그 자동화를 위한 Lambda 함수 생성

boto3 SDK를 활용하여 아래 세 단계의 코드를 작성합니다. 각 단계의 괄호에 참고한 boto3 SDK 함수 링크를 참고합니다.

  1. 로그 보관에 사용할 CloudWatch log group 생성 (create_log_group)
  2. 1번에서 생성한 CloudWatch log group의 보관 주기 설정 (put_retention_policy)
  3. API Gateway Stage의 로깅 활성화 (API Gateway update_stage)

 

CloudWatch log group 생성 및 보관 주기 설정, API Gateway UpdateStage 실행 권한이 필요하므로 lambda → Conguration → Permissions → Execution role에 아래 Policy를 추가합니다.


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "apigateway:PATCH",
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "logs:PutRetentionPolicy",
                "logs:CreateLogGroup"
            ],
            "Resource": "arn:aws:logs:ap-northeast-2:230667876840:*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:ap-northeast-2:230667876840:log-group:/aws/lambda/hh-lmd-update-api-gateway-log-setting:*"
        }
    ]
}

 

EventBridge Rule 생성

API Gateway의 Stage 생성 방식은 직접 생성과 리소스 배포 시 간접 생성 두 가지입니다. 두 이벤트 모두 로그 설정이 필요하므로 Eventbridge rule에 포함시킵니다.

 

CreateDeployment 이벤트 발생

 

 

API Gateway 콘솔 - 스테이지 생성 화면

API Gateway 콘솔 – 스테이지 생성 화면

 

 

CreateDeployment 이벤트 발생

 

 

API Gateway 콘솔 - API 디플로이 화면

API Gateway 콘솔 – API 디플로이 화면

 

 

EventBridge의 자세한 설정법은 이미 CodeBuild 작업 결과 자동화에서 다루었기에 생략합니다.

 

이벤트 패턴 생성

API Gateway에서 발생하는 CreateStage, CreateDeployment 이벤트가 발생할 경우 위에서 생성한

labmda가 실행되도록 대상으로 설정합니다.


{
  "source": ["aws.apigateway"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["apigateway.amazonaws.com"],
    "eventName": ["CreateStage", "CreateDeployment"]
  }
}

 


 

여기까지 EventBridge를 사용한 설정 자동화 사례를 몇 가지 소개했습니다.

 

업무 자동화 활동은 단기적으로는 추가 업무로 생각될 수 있으나 장기적으로는 팀 동료들이 더 중요한 일에 집중할 수 있는 환경을 제공하는데 큰 역할을 한다고 생각합니다.

 

화해 데브옵스팀은 동료들의 업무 생산성과 안정성을 위해 앞으로도 더 많은 자동화 작업을 계획하고 있습니다. 좀 더 흥미로운 사례를 모아 다시 찾아뵙겠습니다.

 

 

 


 

✅ 영석님의 다른 글이 궁금하다면 데브옵스 플랫폼이 선택한 프로비저닝 도구 편을 확인해보세요!

✅ 화해 개발팀의 문화가 궁금하신가요? 그렇다면 화해팀 인사이트 자랑대회 | 3rd DevDay  편을 확인해보세요!

  • 운영효율화
  • AWS
  • EventBridge
  • 자동화
  • 데브옵스
avatar image

장영석 | Devops Engineer

새로운 시도를 즐기는 Devops Engineer입니다.

연관 아티클