

# 예: Datadog 및 Splunk의 알림 통합
<a name="example_integrating_notifications"></a>

이 예제에서는 Datadog 및 Splunk의 알림을 AWS 사고 탐지 및 대응에 통합하는 자세한 단계를 제공합니다.

**Topics**
+ [1단계: Amazon EventBridge에서 APM을 이벤트 소스로 설정](#example_integrating_notifications_step1)
+ [2단계: 사용자 지정 이벤트 버스 생성](#example_integrating_notifications_step2)
+ [3단계: 변환을 위한 AWS Lambda 함수 생성](#example_integrating_notifications_step3)
+ [4단계: 사용자 지정 Amazon EventBridge 규칙 생성](#example_integrating_notifications_step4)

## 1단계: Amazon EventBridge에서 APM을 이벤트 소스로 설정
<a name="example_integrating_notifications_step1"></a>

AWS 계정의 Amazon EventBridge에서 각 APM을 이벤트 소스로 설정합니다. APM을 이벤트 소스로 설정하는 방법에 대한 지침은 [Amazon EventBridge 파트너의 도구에 대한 이벤트 소스 설정 지침](https://console.aws.amazon.com/events/home#/partners)을 참조하세요.

APM을 이벤트 소스로 설정하면 APM에서 AWS 계정의 이벤트 버스로 알림을 수집할 수 있습니다. 설정 후 AWS 사고 탐지 및 대응은 이벤트 버스가 이벤트를 수신할 때 인시던트 관리 프로세스를 시작할 수 있습니다. 이 프로세스는 Amazon EventBridge를 APM의 대상으로 추가합니다.

## 2단계: 사용자 지정 이벤트 버스 생성
<a name="example_integrating_notifications_step2"></a>

사용자 지정 이벤트 버스를 사용하는 것이 가장 좋습니다. AWS 사고 탐지 및 대응은 사용자 지정 이벤트 버스를 사용하여 변환된 이벤트를 수집합니다. AWS Lambda 함수는 파트너 이벤트 버스 이벤트를 변환하여 사용자 지정 이벤트 버스로 전송합니다. AWS 사고 탐지 및 대응은 관리형 규칙을 설치하여 사용자 지정 이벤트 버스에서 이벤트를 수집합니다.

사용자 지정 이벤트 버스 대신 기본 이벤트 버스를 사용할 수 있습니다. AWS 사고 탐지 및 대응은 사용자 지정 규칙 대신 기본 이벤트 버스에서 수집하도록 관리형 규칙을 수정합니다.

**AWS 계정에서 사용자 지정 이벤트 버스를 생성합니다.**

1. Amazon EventBridge 콘솔([https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/))을 엽니다.

1. **버스**, **이벤트 버스**를 선택합니다.

1. **사용자 지정 이벤트 버스**에서 **생성**을 선택합니다.

1. **이름** 아래에 이벤트 버스의 이름을 입력합니다. 권장 형식은 **APMName-AWSIncidentDetectionResponse-EventBus**입니다.

   예를 들어 Datadog 또는 Splunk를 사용하는 경우 다음 중 하나를 사용합니다.
   + **Datadog**: Datadog-AWSIncidentDetectionResponse-EventBus
   + **Splunk**: Splunk-AWSIncidentDetectionResponse-EventBus

## 3단계: 변환을 위한 AWS Lambda 함수 생성
<a name="example_integrating_notifications_step3"></a>

Lambda 함수는 1단계의 파트너 이벤트 버스와 2단계의 사용자 지정(또는 기본) 이벤트 버스 간에 이벤트를 변환합니다. Lambda 함수 변환은 AWS 사고 탐지 및 대응 관리형 규칙과 일치합니다.

**AWS 계정에서 AWS Lambda 함수 생성**

1. AWS Lambda 콘솔에서 [[함수(Functions) 페이지](https://console.aws.amazon.com/lambda/home#/functions)]를 엽니다.

1. **함수 생성**을 선택합니다.

1. **새로 작성** 탭을 선택합니다.

1. **함수 이름**에서 `APMName-AWSIncidentDetectionResponse-LambdaFunction` 형식으로 이름을 입력합니다.

   다음은 Datadog 및 Splunk의 예입니다.
   + **Datadog**: Datadog-AWSIncidentDetectionResponse-LambdaFunction
   + **Splunk**: Splunk-AWSIncidentDetectionResponse-LambdaFunction

1. **런타임**에서 **Python 3.10**을 입력합니다.

1. 남아 있는 필드는 기본값을 그대로 둡니다. **함수 생성**을 선택합니다.

1. **코드 편집** 페이지에서 기본 Lambda 함수 콘텐츠를 다음 코드 예제의 함수로 바꿉니다.

   다음 코드 예제에서 \$1로 시작하는 설명을 기록해 둡니다. 이러한 설명은 변경할 값을 나타냅니다.

   **Datadog 변환 코드 템플릿**:

   ```
   import logging
   import json
   import boto3
   
   logger = logging.getLogger()
   logger.setLevel(logging.INFO)
   
   # Change the EventBusName to the custom event bus name you created previously or use your default event bus which is called 'default'.
   # Example 'Datadog-AWSIncidentDetectionResponse-EventBus'
   EventBusName = "Datadog-AWSIncidentDetectionResponse-EventBus" 
   
   def lambda_handler(event, context):
       # Set the event["detail"]["incident-detection-response-identifier"] value to the name of your alert that is coming from your APM. Each APM is different and each unique alert will have a different name. 
       # Replace the dictionary path, event["detail"]["meta"]["monitor"]["name"], with the path to your alert name based on your APM payload. 
       # This example is for finding the alert name for Datadog.
       event["detail"]["incident-detection-response-identifier"] = event["detail"]["meta"]["monitor"]["name"] 
       logger.info(f"We got: {json.dumps(event, indent=2)}")
       
       client = boto3.client('events')
       response = client.put_events(
        Entries=[
                 {
                  'Detail': json.dumps(event["detail"], indent=2),
                  'DetailType': 'ams.monitoring/generic-apm', # Do not modify. This DetailType value is required.
                  'Source': 'GenericAPMEvent', # Do not modify. This Source value is required.
                  'EventBusName': EventBusName # Do not modify. This variable is set at the top of this code as a global variable. Change the variable value for your eventbus name at the top of this code.    
                }
        ]
       )
       print(response['Entries'])
   ```

   **Splunk 변환 코드 템플릿**:

   ```
   import logging
   import json
   import boto3
   
   logger = logging.getLogger()
   logger.setLevel(logging.INFO)
   
   # Change the EventBusName to the custom event bus name you created previously or use your default event bus which is called 'default'. 
   # Example Splunk-AWSIncidentDetectionResponse-EventBus
   EventBusName = "Splunk-AWSIncidentDetectionResponse-EventBus" 
   
   def lambda_handler(event, context):
       # Set the event["detail"]["incident-detection-response-identifier"] value to the name of your alert that is coming from your APM. Each APM is different and each unique alert will have a different name. 
       # replace the dictionary path event["detail"]["ruleName"] with the path to your alert name based on your APM payload. 
       # This example is for finding the alert name in Splunk.
       event["detail"]["incident-detection-response-identifier"] = event["detail"]["ruleName"]
       logger.info(f"We got: {json.dumps(event, indent=2)}")
       
       client = boto3.client('events')
       response = client.put_events(
       Entries=[
                {
                 'Detail': json.dumps(event["detail"], indent=2),
                 'DetailType': 'ams.monitoring/generic-apm', # Do not modify. This DetailType value is required.
                 'Source': 'GenericAPMEvent', # Do not modify. This Source value is required.
                 'EventBusName': EventBusName # Do not modify. This variable is set at the top of this code as a global variable. Change the variable value for your eventbus name at the top of this code. 
               }
           ]
       )
       print(response['Entries'])
   ```

1. **배포(Deploy)**를 선택합니다.

1. 변환된 데이터를 전송할 이벤트 버스의 Lambda 실행 역할에 **PutEvents** 권한을 추가합니다.

   1. AWS Lambda 콘솔에서 [[함수(Functions) 페이지](https://console.aws.amazon.com/lambda/home#/functions)]를 엽니다.

   1. 함수를 선택한 다음 **구성** 탭에서 **권한**을 선택합니다.

   1. **실행 역할**에서 **역할 이름**을 선택하여 AWS Identity and Access Management 콘솔에서 실행 역할을 엽니다.

   1. **권한 정책**에서 기존 정책 이름을 선택하여 정책을 엽니다.

   1. **이 정책에 정의된 권한**에서 **편집**을 선택합니다.

   1. **정책 편집기** 페이지에서 **새 문 추가**를 선택합니다.

   1. **정책 편집기**는 다음과 유사한 새 빈 문을 추가합니다.  
![\[IAM 콘솔의 JSON 정책 편집기의 스크린샷.\]](http://docs.aws.amazon.com/ko_kr/IDR/latest/userguide/images/iam-add-new-statement.png)

   1. 자동 생성된 새 문을 다음과 같이 바꿉니다.

      ```
      {
        "Sid": "AWSIncidentDetectionResponseEventBus0",
        "Effect": "Allow",
        "Action": "events:PutEvents",
        "Resource": "arn:aws:events:{region}:{accountId}:event-bus/{custom-eventbus-name}"
      }
      ```

   1. **리소스**는 [2단계: 사용자 지정 이벤트 버스 생성](#example_integrating_notifications_step2)에서 생성한 사용자 지정 이벤트 버스의 ARN이거나 Lambda 코드에서 기본 이벤트 버스를 사용하는 경우 기본 이벤트 버스의 ARN입니다.

1. 필요한 권한이 역할에 추가되었는지 검토하고 확인합니다.

1. **이 새 버전을 기본값으로 설정**을 선택한 다음 **변경 사항 저장**을 선택합니다.

**페이로드 변환에는 무엇이 필요한가요?**

AWS 사고 탐지 및 대응에서 수집한 이벤트 버스 이벤트에는 다음 JSON 키:값 페어가 필요합니다.

```
{
    "detail-type": "ams.monitoring/generic-apm",
    "source": "GenericAPMEvent"
    "detail" : {
        "incident-detection-response-identifier": "Your alarm name from your APM",
    }
}
```

다음 예제는 변환 전과 후에 파트너 이벤트 버스의 이벤트를 보여줍니다.

```
{
    "version": "0",
    "id": "a6150a80-601d-be41-1a1f-2c5527a99199",
    "detail-type": "Datadog Alert Notification",
    "source": "aws.partner/datadog.com/Datadog-aaa111bbbc",
    "account": "123456789012",
    "time": "2023-10-25T14:42:25Z",
    "region": "us-east-1",
    "resources": [],
    "detail": {
      "alert_type": "error",
      "event_type": "query_alert_monitor",
      "meta": {
        "monitor": {
          "id": 222222,
          "org_id": 3333333333,
          "type": "query alert",
          "name": "UnHealthyHostCount",
          "message": "@awseventbridge-Datadog-aaa111bbbc",
          "query": "max(last_5m):avg:aws.applicationelb.un_healthy_host_count{aws_account:123456789012} \u003c\u003d 1",
          "created_at": 1686884769000,
          "modified": 1698244915000,
          "options": {
            "thresholds": {
              "critical": 1.0
            }
          },
        },
        "result": {
          "result_id": 7281010972796602670,
          "result_ts": 1698244878,
          "evaluation_ts": 1698244868,
          "scheduled_ts": 1698244938,
          "metadata": {   
            "monitor_id": 222222,
            "metric": "aws.applicationelb.un_healthy_host_count"
          }
        },
        "transition": {
          "trans_name": "Triggered",
          "trans_type": "alert"
        },
        "states": {
          "source_state": "OK",
          "dest_state": "Alert"
        },
        "duration": 0
      },
      "priority": "normal",
      "source_type_name": "Monitor Alert",
      "tags": [
        "aws_account:123456789012",
        "monitor"
      ]
    }
}
```

이벤트가 변환되기 전에 `detail-type`은 알림의 출처가 되고, 소스가 파트너 APM이고, `incident-detection-response-identifier` 키가 없음을 나타냅니다.

Lambda 함수는 위의 이벤트를 변환하여 대상 사용자 지정 또는 기본 이벤트 버스에 넣습니다. 변환된 페이로드에는 이제 필요한 키:값 페어가 포함됩니다.

```
{
    "version": "0",
    "id": "7f5e0fc1-e917-2b5d-a299-50f4735f1283",
    "detail-type": "ams.monitoring/generic-apm",
    "source": "GenericAPMEvent",
    "account": "123456789012",
    "time": "2023-10-25T14:42:25Z",
    "region": "us-east-1",
    "resources": [],
    "detail": {
      "incident-detection-response-identifier": "UnHealthyHostCount",
      "alert_type": "error",
      "event_type": "query_alert_monitor",
      "meta": {
        "monitor": {
          "id": 222222,
          "org_id": 3333333333,
          "type": "query alert",
          "name": "UnHealthyHostCount",
          "message": "@awseventbridge-Datadog-aaa111bbbc",
          "query": "max(last_5m):avg:aws.applicationelb.un_healthy_host_count{aws_account:123456789012} \u003c\u003d 1",
          "created_at": 1686884769000,
          "modified": 1698244915000,
          "options": {
            "thresholds": {
              "critical": 1.0
            }
          },
        },
        "result": {
          "result_id": 7281010972796602670,
          "result_ts": 1698244878,
          "evaluation_ts": 1698244868,
          "scheduled_ts": 1698244938,
          "metadata": {
            "monitor_id": 222222,
            "metric": "aws.applicationelb.un_healthy_host_count"
          }
        },
        "transition": {
          "trans_name": "Triggered",
          "trans_type": "alert"
        },
        "states": {
          "source_state": "OK",
          "dest_state": "Alert"
        },
        "duration": 0
      },
      "priority": "normal",
      "source_type_name": "Monitor Alert",
      "tags": [
        "aws_account:123456789012",
        "monitor"
      ]
    }
}
```

이제 `detail-type`이 `ams.monitoring/generic-apm`이고, 소스가 `GenericAPMEvent`이며, 세부 사항에 새 키:값 페어 `incident-detection-response-identifier`가 있습니다.

 앞의 예에서 `incident-detection-response-identifier` 값은 경로 `$.detail.meta.monitor.name` 아래의 알림 이름에서 가져옵니다. APM 알림 이름 경로는 한 APM에서 다른 APM으로 다릅니다. 올바른 파트너 이벤트 JSON 경로에서 경보 이름을 가져와 `incident-detection-response-identifier` 값에 사용하도록 Lambda 함수를 수정해야 합니다.

`incident-detection-response-identifier`에 설정된 각 고유 이름은 온보딩 중에 AWS 사고 탐지 및 대응 팀에 제공됩니다. `incident-detection-response-identifier`의 이름을 알 수 없는 이벤트는 처리되지 않습니다.

## 4단계: 사용자 지정 Amazon EventBridge 규칙 생성
<a name="example_integrating_notifications_step4"></a>

1단계에서 생성된 파트너 이벤트 버스에는 생성한 EventBridge 규칙이 필요합니다. 규칙은 파트너 이벤트 버스에서 3단계에서 생성된 Lambda 함수로 원하는 이벤트를 전송합니다.

EventBridge 규칙 정의에 대한 지침은 [Amazon EventBridge 규칙](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-rules.html)을 참조하세요.

1. Amazon EventBridge 콘솔([https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/))을 엽니다.

1. **규칙**을 선택한 다음 APM과 연결된 파트너 이벤트 버스를 선택합니다. 다음은 파트너 이벤트 버스의 예입니다.
   + **Datadog:** aws.partner/datadog.com/eventbus-name
   + **Splunk:** aws.partner/signalfx.com/RandomString

1. **규칙 생성**을 선택하여 새 EventBridge 규칙을 생성합니다.

1. 규칙 이름에 `APMName-AWS Incident Detection and Response-EventBridgeRule` 형식의 이름을 입력한 후 **다음**을 선택합니다. 예를 들어, 다음 이름과 같습니다.
   + **Datadog:** Datadog-AWSIncidentDetectionResponse-EventBridgeRule
   + **Splunk:** Splunk-AWSIncidentDetectionResponse-EventBridgeRule

1. **이벤트 소스**에서 **AWS 이벤트 또는 EventBridge 파트너 이벤트**를 선택합니다.

1. **샘플 이벤트** 및 **생성 방법**을 기본값으로 둡니다.

1. **이벤트 패턴**에서 다음을 선택합니다.

   1. **이벤트 소스:** EventBridge 파트너.

   1. **파트너:** APM 파트너를 선택합니다.

   1. **이벤트 유형:** 모든 이벤트.

   다음은 예제 이벤트 패턴입니다.

   **예제 Datadog 이벤트 패턴**  
![\[Datadog 이벤트 패턴의 예입니다.\]](http://docs.aws.amazon.com/ko_kr/IDR/latest/userguide/images/datadog-event-pattern.png)

   **Splunk 이벤트 패턴 예제**  
![\[Splunk 이벤트 패턴의 예입니다.\]](http://docs.aws.amazon.com/ko_kr/IDR/latest/userguide/images/splunk-event-pattern.png)

1. **대상**에서 다음을 선택합니다.

   1. **대상 유형:** AWS 서비스

   1. **대상 선택:** Lambda 함수를 선택합니다.

   1. **함수:** 2단계에서 생성한 Lambda 함수의 이름입니다.

1. **다음**, **규칙 저장**을 선택합니다.