

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 구독을 통한 로그 데이터 실시간 처리
<a name="Subscriptions"></a>

구독을 사용하여 CloudWatch Logs에서 나온 로그 이벤트의 실시간 피드에 액세스하고, 사용자 지정 처리, 분석 또는 다른 시스템으로의 로드를 위해 다른 서비스(예: Amazon Kinesis 스트림, Amazon Data Firehose 스트림 또는 AWS Lambda )에 이를 전송할 수 있습니다. 로그 이벤트가 수신 서비스로 전송되면 base64로 인코딩되고 gzip 형식으로 압축됩니다.

CloudWatch Logs 중앙 집중화를 사용하여 여러 계정 및 리전의 로그 데이터를 중앙 위치로 복제할 수도 있습니다. 자세한 내용은 [교차 계정 교차 리전 로그 중앙 집중화](CloudWatchLogs_Centralization.md) 단원을 참조하십시오.

로그 이벤트 구독을 시작하려면 이벤트가 전달될 Amazon Kinesis Data Streams 스트림과 같은 수신 리소스를 생성합니다. 구독 필터는 AWS 리소스에 전달되는 로그 이벤트와 일치하는 로그 이벤트를 전송할 대상에 대한 정보를 필터링하는 데 사용할 필터 패턴을 정의합니다. 로그 이벤트는 수집 직후, 일반적으로 3분 이내에 수신 리소스로 전송됩니다.

**참고**  
구독이 있는 로그 그룹이 로그 변환을 사용하는 경우 필터 패턴은 로그 이벤트의 변환된 버전과 비교됩니다. 자세한 내용은 [수집 중 로그 변환](CloudWatch-Logs-Transformation.md) 단원을 참조하십시오.

계정 수준 및 로그 그룹 수준에서 구독을 생성할 수 있습니다. 각 계정은 리전별 하나의 계정 수준 구독 필터를 가질 수 있습니다. 각 로그 그룹에는 구독 필터를 최대 2개까지 연결할 수 있습니다.

**참고**  
대상 서비스가 조절 예외 또는 재시도 가능한 서비스 예외(예: HTTP 5xx)와 같은 재시도 가능한 오류를 반환하는 경우 CloudWatch Logs는 최대 24시간 동안 계속해서 전송을 다시 시도합니다. AccessDeniedException 또는 ResourceNotFoundException과 같이 다시 시도할 수 없는 오류인 경우 CloudWatch Logs는 다시 전송을 시도하지 않습니다. 이러한 경우 구독 필터가 최대 10분 동안 비활성화된 다음 CloudWatch Logs가 대상에 로그 전송을 재시도합니다. 이 비활성화된 기간 동안에는 로그를 건너뜁니다.

또한 CloudWatch Logs는 구독 서비스로의 로그 이벤트 전달에 대한 CloudWatch 지표를 생성합니다. 자세한 내용은 [CloudWatch 지표를 사용한 모니터링](CloudWatch-Logs-Monitoring-CloudWatch-Metrics.md) 단원을 참조하십시오.

 CloudWatch Logs 구독을 사용하여 로그 데이터를 거의 실시간으로 Amazon OpenSearch Service 클러스터로 스트리밍할 수도 있습니다. 자세한 내용은 [Streaming CloudWatch Logs data to Amazon OpenSearch Service](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_OpenSearch_Stream.html)을 참조하세요.

구독은 Standard 로그 클래스의 로그 그룹에서만 지원됩니다. 로그 클래스에 대한 자세한 내용은 [로그 클래스](CloudWatch_Logs_Log_Classes.md)를 참조하세요.

**참고**  
구독 필터는 로그 이벤트를 배칭하여 전송을 최적화하고 대상에 대한 직접 호출의 양을 줄일 수 있습니다. 배칭은 보장되지는 않지만 가능하면 사용됩니다.

일정에 따른 로그 데이터의 배치 처리 및 분석의 경우를 사용하는 것이 좋습니다[예약된 쿼리를 사용하여 로그 분석 자동화](ScheduledQueries.md). 예약된 쿼리는 CloudWatch Logs Insights 쿼리를 자동으로 실행하고 Amazon S3 버킷 또는 Amazon EventBridge 이벤트 버스와 같은 대상에 결과를 전달합니다.

**참고**  
구독 필터는 이벤트 전송을 한 번 이상 보장하지만 중복 이벤트가 가끔 발생할 수 있습니다.

**Topics**
+ [개념](subscription-concepts.md)
+ [로그 그룹 수준 구독 필터](SubscriptionFilters.md)
+ [계정 수준 구독 필터](SubscriptionFilters-AccountLevel.md)
+ [교차 계정 교차 리전 구독](CrossAccountSubscriptions.md)
+ [혼동된 대리자 방지](Subscriptions-confused-deputy.md)
+ [로그 재귀 방지](Subscriptions-recursion-prevention.md)

# 개념
<a name="subscription-concepts"></a>

각 구독 필터는 다음과 같은 키 요소로 이루어져 있습니다.

**필터 패턴**  
CloudWatch Logs가 대상 AWS 리소스로 전송되는 항목을 제한하는 필터링 표현식과 함께 각 로그 이벤트의 데이터를 해석하는 방법에 대한 심볼 설명입니다. 필터 패턴 구문에 대한 자세한 내용은 [지표 필터, 구독 필터, 필터 로그 이벤트 및 Live Tail에 대한 필터 패턴 구문](FilterAndPatternSyntax.md)을 참조하세요.

**대상 ARN**  
구독 피드의 대상으로 사용할 Amazon Kinesis Data Streams 스트림, Firehose 스트림 또는 Lambda 함수의 Amazon 리소스 이름(ARN)입니다.

**역할 ARN**  
선택한 대상으로 데이터를 입력하기 위해 CloudWatch Logs에 필요한 권한을 부여하는 IAM 역할입니다. 이 역할은 Lambda 대상에는 필요하지 않습니다. CloudWatch Logs가 Lambda 함수 자체에 대한 액세스 제어 설정에 필요한 권한을 얻을 수 있기 때문입니다.

**배포**  
대상이 Amazon Kinesis Data Streams의 스트림일 때 해당 대상으로 로그 데이터를 배포하는 데 사용되는 방법입니다. 기본적으로 로그 스트림에 따라 로그 데이터가 그룹화됩니다. 보다 균등한 배포를 위해 로그 데이터를 무작위로 그룹화할 수 있습니다.

로그 그룹 수준 구독의 경우 다음 키 요소도 포함됩니다.

**log\$1group\$1name**  
구독 필터에 연결되는 로그 그룹. 이 로그 그룹에 업로드되는 모든 로그 이벤트는 구독 필터를 따르게 되며, 필터와 일치하는 로그 이벤트는 일치하는 로그 이벤트를 수신하는 대상 서비스로 전송됩니다.

계정 수준 구독의 경우 다음 키 요소도 포함됩니다.

**선택 기준**  
계정 수준 구독 필터가 적용되는 로그 그룹을 선택하는 데 사용되는 기준입니다. 이를 지정하지 않으면 계정 수준 구독 필터가 계정의 모든 로그 그룹에 적용됩니다. 이 필드는 무한 로그 루프를 방지하는 데 사용됩니다. 무한 로그 루프 문제에 대한 자세한 내용은 [로그 재귀 방지](Subscriptions-recursion-prevention.md)을 참조하세요.  
선택 기준의 크기 한도는 25KB입니다.

중앙 집중식 로그 그룹의 경우 다음 키 요소도 포함됩니다. 이러한 요소를 필드 선택 기준으로 사용하여 로그 데이터의 소스를 식별할 수 있으므로 중앙 집중식 로그에서 파생된 지표를 보다 세밀하게 필터링하고 분석할 수 있습니다.

**@aws.account**  
이 필드는 로그 이벤트가 시작된 AWS 계정 ID를 식별합니다.

**@aws.region**  
이 필드는 로그 이벤트가 생성된 AWS 리전을 식별합니다.

# 로그 그룹 수준 구독 필터
<a name="SubscriptionFilters"></a>

 Amazon Kinesis Data Streams, Amazon AWS Lambda Data Firehose 또는 Amazon OpenSearch Service에서 구독 필터를 사용할 수 있습니다. 구독 필터를 통해 서비스로 전송되는 로그는 base64로 인코딩되고 gzip 형식으로 압축됩니다. 에서 중앙 집중식 로그를 사용하는 경우 `@aws.account` 및 `@aws.region` 시스템 필드를 내보내 조직의 어떤 계정 및 리전에서 어떤 데이터가 오는지 식별할 AWS Organizations수 있습니다. 이 섹션에서는 Firehose, Lambda, Amazon Kinesis Data Streams 및 OpenSearch Service로 로그 데이터를 전송하는 CloudWatch Logs 구독 필터를 생성하는 데 따를 수 있는 예제를 제공합니다.

**참고**  
 로그 데이터를 검색하려면 [필터 및 패턴 구문](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html)을 참조하세요.

**Topics**
+ [예제 1: Amazon Kinesis Data Streams를 사용한 구독 필터](#DestinationKinesisExample)
+ [예제 2:를 사용한 구독 필터 AWS Lambda](#LambdaFunctionExample)
+ [예제 3: Amazon Data Firehose에 대한 구독 필터](#FirehoseExample)
+ [예제 4: Amazon OpenSearch Service를 사용한 구독 필터](#OpenSearchExample)

## 예제 1: Amazon Kinesis Data Streams를 사용한 구독 필터
<a name="DestinationKinesisExample"></a>

다음 예제에서는 AWS CloudTrail 이벤트를 포함하는 로그 그룹에 구독 필터를 연결합니다. 구독 필터는 "RootAccess"라는 Amazon Kinesis Data Streams의 스트림에 "Root" AWS 자격 증명에 의해 수행된 모든 로깅된 활동을 전달합니다.RootAccess." CloudWatch Logs로 AWS CloudTrail 이벤트를 전송하는 방법에 대한 자세한 내용은 *AWS CloudTrail 사용 설명서*의 [CloudWatch Logs로 CloudTrail CloudTrail 이벤트 전송](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cw_send_ct_events.html)을 참조하세요.

**참고**  
스트림을 생성하기 전에 생성할 로그 데이터의 볼륨을 계산합니다. 이 볼륨을 처리하기에 충분한 샤드로 스트림을 생성해야 합니다. 스트림에 샤드가 충분하지 않은 경우 로그 스트림에 스로틀링이 발생합니다. 스트림 볼륨 제한 사항에 대한 자세한 내용은 [Quotas and Limits](https://docs.aws.amazon.com/streams/latest/dev/service-sizes-and-limits.html)을 참조하세요.  
제한된 결과물은 최대 24시간 동안 재시도됩니다. 24시간이 지나면 실패한 결과물이 삭제됩니다.  
스로틀링 현상의 위험을 완화하려면 다음 단계를 수행합니다.  
[ PutSubscriptionFilter](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutSubscriptionFilter.html#CWL-PutSubscriptionFilter-request-distribution) 또는 [ put-subscription-filter](https://awscli.amazonaws.com/v2/documentation/api/2.4.18/reference/logs/put-subscription-filter.html)를 사용하여 구독 필터를 생성할 때 `distribution`에 `random`을 지정합니다. 기본적으로 스트림 필터 배포는 로그 스트림에 의해 이루어지며, 이로 인해 스로틀링 현상이 발생할 수 있습니다.
CloudWatch 지표를 사용하여 스트림 모니터링합니다. 이렇게 하면 제한을 식별하고 그에 따라 구성을 조정할 수 있습니다. 예를 들어, `DeliveryThrottling` 지표는 데이터를 구독 대상으로 전달할 때 CloudWatch Logs에 스로틀링이 발생한 로그 이벤트의 수를 추적하는 데 사용될 수 있습니다. 모니터링에 대한 자세한 내용은 [CloudWatch 지표를 사용한 모니터링](CloudWatch-Logs-Monitoring-CloudWatch-Metrics.md)을 참조하세요.
Amazon Kinesis Data Streams에서 스트림에 대한 온디맨드 용량 모드를 사용합니다. 온디맨드 모드는 워크로드가 확장 또는 축소될 때 즉시 워크로드를 수용합니다. 온디맨드 용량 모드에 대한 자세한 내용은 [온디맨드 모드](https://docs.aws.amazon.com/streams/latest/dev/how-do-i-size-a-stream.html#ondemandmode)를 참조하세요.
Amazon Kinesis Data Streams의 스트림 용량과 일치하도록 CloudWatch 구독 필터 패턴을 제한합니다. 스트림에 너무 많은 데이터를 전송하는 경우 필터 크기를 줄이거나 필터 기준을 조정해야 할 수 있습니다.

**Amazon Kinesis Data Streams에 대한 구독 필터를 생성하려면**

1. 다음 명령을 사용하여 대상 스트림을 생성합니다.

   ```
   $ C:\>  aws kinesis create-stream --stream-name "RootAccess" --shard-count 1
   ```

1. 스트림이 활성 상태가 될 때까지 기다립니다(1\$12분 정도 소요). 다음 Amazon Kinesis Data Streams [describe-stream](https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html) 명령을 사용하여 **StreamDescription.StreamStatus** 속성을 확인할 수 있습니다. 또한 이후 단계에서 필요할 수 있기 때문에 **StreamDescription.StreamARN** 값을 적어둡니다.

   ```
   aws kinesis describe-stream --stream-name "RootAccess"
   ```

   다음은 예제 출력입니다.

   ```
   {
       "StreamDescription": {
           "StreamStatus": "ACTIVE",
           "StreamName": "RootAccess",
           "StreamARN": "arn:aws:kinesis:us-east-1:123456789012:stream/RootAccess",
           "Shards": [
               {
                   "ShardId": "shardId-000000000000",
                   "HashKeyRange": {
                       "EndingHashKey": "340282366920938463463374607431768211455",
                       "StartingHashKey": "0"
                   },
                   "SequenceNumberRange": {
                       "StartingSequenceNumber":
                       "49551135218688818456679503831981458784591352702181572610"
                   }
               }
           ]
       }
   }
   ```

1. 스트림에 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 신뢰 정책을 파일로 생성해야 합니다(예: `~/TrustPolicyForCWL-Kinesis.json`). 텍스트 편집기를 사용하여 이 정책을 생성합니다. IAM 콘솔을 사용하여 정책을 생성하지 마세요.

   이 정책에는 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키가 포함되어 있습니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 섹션을 참조하세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole",
       "Condition": { 
           "StringLike": { "aws:SourceArn": "arn:aws:logs:region:123456789012:*" } 
        }
      }
   }
   ```

1. **create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이후 단계에서 필요할 수 있기 때문에 반환된 **Role.Arn** 값을 적어둡니다.

   ```
   aws iam create-role --role-name CWLtoKinesisRole --assume-role-policy-document file://~/TrustPolicyForCWL-Kinesis.json
   ```

   다음은 출력의 예제입니다.

   ```
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   },
                   "Condition": { 
                       "StringLike": { 
                           "aws:SourceArn": { "arn:aws:logs:region:123456789012:*" }
                       } 
                   }
               }
           },
           "RoleId": "AAOIIAH450GAB4HC5F431",
           "CreateDate": "2015-05-29T13:46:29.431Z",
           "RoleName": "CWLtoKinesisRole",
           "Path": "/",
           "Arn": "arn:aws:iam::123456789012:role/CWLtoKinesisRole"
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 파일에 권한 정책을 생성합니다(예: `~/PermissionsForCWL-Kinesis.json`). 텍스트 편집기를 사용하여 이 정책을 생성합니다. IAM 콘솔을 사용하여 정책을 생성하지 마세요.

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "kinesis:PutRecord",
         "Resource": "arn:aws:kinesis:region:123456789012:stream/RootAccess"
       }
     ]
   }
   ```

1. 다음 [put-role-policy](https://docs.aws.amazon.com/cli/latest/reference/iam/put-role-policy.html) 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy  --role-name CWLtoKinesisRole  --policy-name Permissions-Policy-For-CWL  --policy-document file://~/PermissionsForCWL-Kinesis.json
   ```

1. 스트림이 **Active** 상태에 있고 IAM 역할을 생성하고 나면 CloudWatch Logs 구독 필터를 생성할 수 있습니다. 그 즉시 구독 필터는 실시간으로 선택한 로그 그룹에서 스트림으로 로그 데이터를 이동시키기 시작합니다.

   ```
   aws logs put-subscription-filter \
       --log-group-name "CloudTrail/logs" \
       --filter-name "RootAccess" \
       --filter-pattern "{$.userIdentity.type = Root}" \
       --destination-arn "arn:aws:kinesis:region:123456789012:stream/RootAccess" \
       --role-arn "arn:aws:iam::123456789012:role/CWLtoKinesisRole"
   ```

1. 구독 필터를 설정하고 나면 CloudWatch Logs는 들어오는 모든 로그 이벤트 중에서 필터 패턴과 일치하는 이벤트를 스트림으로 전달합니다. Amazon Kinesis Data Streams 샤드 반복기를 잡고 Amazon Kinesis Data Streams get-records 명령을 사용하여 일부 Amazon Kinesis Data Streams 레코드를 가져와서이 문제가 발생하고 있는지 확인할 수 있습니다.

   ```
   aws kinesis get-shard-iterator --stream-name RootAccess --shard-id shardId-000000000000 --shard-iterator-type TRIM_HORIZON
   ```

   ```
   {
       "ShardIterator":
       "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiK2OSh0uP"
   }
   ```

   ```
   aws kinesis get-records --limit 10 --shard-iterator "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiK2OSh0uP"
   ```

   Amazon Kinesis Data Streams가 데이터를 반환하기 전에이 호출을 몇 번 수행해야 할 수 있습니다.

   레코드 어레이에서 응답을 확인할 수 있습니다. Amazon Kinesis **Data** Streams 레코드의 데이터 속성은 base64로 인코딩되고 gzip 형식으로 압축됩니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

   ```
   echo -n "<Content of Data>" | base64 -d | zcat
   ```

   디코딩 및 압축 해제된 base64 데이터는 다음 구조를 가진 JSON으로 포맷됩니다.

   ```
   {
       "owner": "111111111111",
       "logGroup": "CloudTrail/logs",
       "logStream": "111111111111_CloudTrail/logs_us-east-1",
       "subscriptionFilters": [
           "Destination"
       ],
       "messageType": "DATA_MESSAGE",
       "logEvents": [
           {
               "id": "31953106606966983378809025079804211143289615424298221568",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           },
           {
               "id": "31953106606966983378809025079804211143289615424298221569",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           },
           {
               "id": "31953106606966983378809025079804211143289615424298221570",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           }
       ]
   }
   ```

   위의 데이터 구조에서 키 요소는 다음과 같습니다.  
**owner**  
원본 로그 데이터의 AWS 계정 ID입니다.  
**logGroup**  
원본 로그 데이터의 로그 그룹 이름.  
**logStream**  
원본 로그 데이터의 로그 스트림 이름.  
**subscriptionFilters**  
원본 로그 데이터과 일치한 구독 필터 이름 목록입니다.  
**messageType**  
데이터 메시지는 'DATA\$1MESSAGE' 유형을 사용합니다. CloudWatch Logs는 주로 대상에 연결할 수 있는지 확인하기 위해 "CONTROL\$1MESSAGE" 유형의 Amazon Kinesis Data Streams 레코드를 내보낼 수 있습니다.  
**logEvents**  
로그 이벤트 레코드의 배열로 표현되는 실제 로그 데이터. 'ID' 속성은 모든 로그 이벤트의 고유 식별자입니다.

## 예제 2:를 사용한 구독 필터 AWS Lambda
<a name="LambdaFunctionExample"></a>

이 예제에서는 AWS Lambda 함수에 로그 데이터를 전송하는 CloudWatch Logs 구독 필터를 생성합니다.

**참고**  
Lambda 함수를 생성하기 전에 생성할 로그 데이터의 볼륨을 계산합니다. 이 볼륨을 처리할 수 있는 함수를 생성해야 합니다. 함수에 볼륨이 충분하지 않은 경우 로그 스트림에 스로틀링이 발생합니다. [AWS Lambda 제한 사항](https://docs.aws.amazon.com/lambda/latest/dg/limits.html)에 대한 자세한 내용은 Lambda 제한 사항을 참조하세요.

**Lambda에 대한 구독 필터를 생성하려면**

1.  AWS Lambda 함수를 생성합니다.

   Lambda 실행 역할이 설정되었는지 확인합니다. 자세한 내용은 *AWS Lambda Developer Guide*의 [Step 2.2: Create an IAM Role (execution role)](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)을 참조하세요.

1. 다음 콘텐츠로 텍스트 편집기를 열고 `helloWorld.js`라는 파일을 생성합니다.

   ```
   var zlib = require('zlib');
   exports.handler = function(input, context) {
       var payload = Buffer.from(input.awslogs.data, 'base64');
       zlib.gunzip(payload, function(e, result) {
           if (e) { 
               context.fail(e);
           } else {
               result = JSON.parse(result.toString());
               console.log("Event Data:", JSON.stringify(result, null, 2));
               context.succeed();
           }
       });
   };
   ```

1. helloWorld.js 파일을 압축하고 `helloWorld.zip`라는 이름으로 저장합니다.

1. 역할이 첫 단계에서 설정한 Lambda 실행 역할인 경우에는 다음 명령을 사용합니다.

   ```
   aws lambda create-function \
       --function-name helloworld \
       --zip-file fileb://file-path/helloWorld.zip \
       --role lambda-execution-role-arn \
       --handler helloWorld.handler \
       --runtime nodejs12.x
   ```

1. CloudWatch Logs에 함수를 실행할 권한을 부여합니다. 다음 명령을 사용하여 자리 표시자 계정을 자체 계정으로, 자리 표시자 그룹을 처리할 로그 그룹으로 바꿉니다.

   ```
   aws lambda add-permission \
       --function-name "helloworld" \
       --statement-id "helloworld" \
       --principal "logs.amazonaws.com" \
       --action "lambda:InvokeFunction" \
       --source-arn "arn:aws:logs:region:123456789123:log-group:TestLambda:*" \
       --source-account "123456789012"
   ```

1. 다음 명령을 사용하여 구독 필터를 생성하여 자리 표시자 계정을 자체 계정으로, 자리 표시자 그룹을 처리할 로그 그룹으로 바꿉니다.

   ```
   aws logs put-subscription-filter \
       --log-group-name myLogGroup \
       --filter-name demo \
       --filter-pattern "" \
       --destination-arn arn:aws:lambda:region:123456789123:function:helloworld
   ```

1. (선택 사항) 샘플 로그 이벤트를 사용하여 테스트합니다. 명령 프롬프트에서 다음 명령을 실행하여 구독된 스트림으로 간단한 로그 메시지를 보냅니다.

   Lambda 함수의 출력을 보려면 /aws/lambda/helloworld에 출력이 표시되는 Lambda 함수를 탐색합니다.

   ```
   aws logs put-log-events --log-group-name myLogGroup --log-stream-name stream1 --log-events "[{\"timestamp\":<CURRENT TIMESTAMP MILLIS> , \"message\": \"Simple Lambda Test\"}]"
   ```

   Lambda의 배열로 응답을 확인할 수 있습니다. Lambda 레코드의 **데이터** 속성은 base64로 인코딩되고 gzip 형식으로 압축됩니다. Lambda가 수신하는 실제 페이로드는 `{ "awslogs": {"data": "BASE64ENCODED_GZIP_COMPRESSED_DATA"} }` 형식을 따릅니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

   ```
   echo -n "<BASE64ENCODED_GZIP_COMPRESSED_DATA>" | base64 -d | zcat
   ```

   디코딩 및 압축 해제된 base64 데이터는 다음 구조를 가진 JSON으로 포맷됩니다.

   ```
   {
       "owner": "123456789012",
       "logGroup": "CloudTrail",
       "logStream": "123456789012_CloudTrail_us-east-1",
       "subscriptionFilters": [
           "Destination"
       ],
       "messageType": "DATA_MESSAGE",
       "logEvents": [
           {
               "id": "31953106606966983378809025079804211143289615424298221568",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           },
           {
               "id": "31953106606966983378809025079804211143289615424298221569",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           },
           {
               "id": "31953106606966983378809025079804211143289615424298221570",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           }
       ]
   }
   ```

   위의 데이터 구조에서 키 요소는 다음과 같습니다.  
**owner**  
원본 로그 데이터의 AWS 계정 ID입니다.  
**logGroup**  
원본 로그 데이터의 로그 그룹 이름.  
**logStream**  
원본 로그 데이터의 로그 스트림 이름.  
**subscriptionFilters**  
원본 로그 데이터과 일치한 구독 필터 이름 목록입니다.  
**messageType**  
데이터 메시지는 'DATA\$1MESSAGE' 유형을 사용합니다. 때로 CloudWatch Logs는 주로 대상이 도달 가능한지 확인하기 위한 목적으로 'CONTROL\$1MESSAGE' 유형을 가진 Lambda 레코드를 출력할 수 있습니다.  
**logEvents**  
로그 이벤트 레코드의 배열로 표현되는 실제 로그 데이터. 'ID' 속성은 모든 로그 이벤트의 고유 식별자입니다.

## 예제 3: Amazon Data Firehose에 대한 구독 필터
<a name="FirehoseExample"></a>

이 예제에서는 수신 로그 이벤트 중에서 정의된 필터와 일치하는 이벤트를 Amazon Data Firehose 전송 스트림에 전송하는 CloudWatch Logs 구독을 생성합니다. CloudWatch Logs에서 Amazon Data Firehose로 전송된 데이터는 이미 gzip 6 수준의 압축이 되었기 때문에 Firehose 전송 스트림 내에서 압축을 사용할 필요가 없습니다. 그런 다음 Firehose의 압축 해제 기능을 사용하여 로그를 자동으로 압축 해제할 수 있습니다. 자세한 내용은 [Firehose에 CloudWatch Logs 전송](https://docs.aws.amazon.com/logs/SubscriptionFilters.html#FirehoseExample)을 참조하세요.

**참고**  
Firehose 스트림을 생성하기 전에 생성될 로그 데이터의 볼륨을 계산합니다. 이 볼륨을 처리할 수 있는 Firehose 스트림을 생성해야 합니다. 스트림이 볼륨을 처리할 수 없는 경우 로그 스트림에 스로틀링이 발생합니다. Firehose 스트림 볼륨 제한 사항에 대한 자세한 내용은 [Amazon Data Firehose 데이터 제한 사항](https://docs.aws.amazon.com/firehose/latest/dev/limits.html)을 참조하세요.

**Firehose 구독 필터를 생성하려면**

1. Amazon Simple Storage Service(Amazon S3) 버킷을 생성합니다. CloudWatch Logs를 위해 특별히 생성한 버킷을 사용하는 것이 좋습니다. 그러나 기존 버킷을 사용하고 싶으면 2단계로 건너뛸 수 있습니다.

   다음 명령을 실행하여 자리 표시자 리전을 사용하고자 하는 리전으로 바꿉니다.

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-bucket2 --create-bucket-configuration LocationConstraint=region
   ```

   다음은 예제 출력입니다.

   ```
   {
       "Location": "/amzn-s3-demo-bucket2"
   }
   ```

1. Amazon S3 버킷에 데이터를 입력하는 데 필요한 권한을 Amazon Data Firehose에 부여하는 IAM 역할을 생성합니다.

   자세한 내용은 *Amazon Data Firehose 개발자 가이드*의 [Amazon Data Firehose를 사용하여 액세스 제어](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html)를 참조하세요.

   먼저 텍스트 편집기를 사용하여 다음과 같이 `~/TrustPolicyForFirehose.json` 파일에 신뢰 정책을 생성합니다.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "firehose.amazonaws.com" },
       "Action": "sts:AssumeRole"
       } 
   }
   ```

1. **create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이후 단계에서 필요할 수 있기 때문에 반환된 **Role.Arn** 값을 적어둡니다.

   ```
   aws iam create-role \
    --role-name FirehosetoS3Role \
    --assume-role-policy-document file://~/TrustPolicyForFirehose.json
   
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "firehose.amazonaws.com"
                   }
               }
           },
           "RoleId": "AAOIIAH450GAB4HC5F431",
           "CreateDate": "2015-05-29T13:46:29.431Z",
           "RoleName": "FirehosetoS3Role",
           "Path": "/",
           "Arn": "arn:aws:iam::123456789012:role/FirehosetoS3Role"
       }
   }
   ```

1. Firehose가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 `~/PermissionsForFirehose.json` 파일엣 권한 정책을 생성합니다.

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [ 
             "s3:AbortMultipartUpload", 
             "s3:GetBucketLocation", 
             "s3:GetObject", 
             "s3:ListBucket", 
             "s3:ListBucketMultipartUploads", 
             "s3:PutObject" ],
         "Resource": [ 
             "arn:aws:s3:::amzn-s3-demo-bucket2", 
             "arn:aws:s3:::amzn-s3-demo-bucket2/*" ]
       }
     ]
   }
   ```

1. 다음 put-role-policy 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy --role-name FirehosetoS3Role --policy-name Permissions-Policy-For-Firehose --policy-document file://~/PermissionsForFirehose.json
   ```

1. 다음과 같이 대상 Firehose 전송 시스템을 생성하여 **RoleARN** 및 **BucketARN**의 자리 표시자 값을 생성한 역할 및 버킷 ARN으로 바꿉니다.

   ```
   aws firehose create-delivery-stream \
      --delivery-stream-name 'my-delivery-stream' \
      --s3-destination-configuration \
     '{"RoleARN": "arn:aws:iam::123456789012:role/FirehosetoS3Role", "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket2"}'
   ```

   Firehose는 제공된 Amazon S3 객체에서 YYYY/MM/DD/HH UTC 시간 형식의 접두사를 자동으로 사용합니다. 시간 형식 접두사 앞에 추가할 또 다른 접두사를 지정할 수 있습니다. 슬래시(/)로 끝난 접두사는 Amazon S3 버킷에서 자리 표시자로 표시됩니다.

1. 스트림이 활성 상태가 될 때까지 기다립니다(몇 분 소요). Firehose **describe-delivery-stream** 명령을 사용하여 **DeliveryStreamDescription.DeliveryStreamStatus** 속성을 확인할 수 있습니다. 또한 이후 단계에서 필요할 수 있기 때문에 **DeliveryStreamDescription.DeliveryStreamARN** 값을 적어둡니다.

   ```
   aws firehose describe-delivery-stream --delivery-stream-name "my-delivery-stream"
   {
       "DeliveryStreamDescription": {
           "HasMoreDestinations": false,
           "VersionId": "1",
           "CreateTimestamp": 1446075815.822,
           "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789012:deliverystream/my-delivery-stream",
           "DeliveryStreamStatus": "ACTIVE",
           "DeliveryStreamName": "my-delivery-stream",
           "Destinations": [
               {
                   "DestinationId": "destinationId-000000000001",
                   "S3DestinationDescription": {
                       "CompressionFormat": "UNCOMPRESSED",
                       "EncryptionConfiguration": {
                           "NoEncryptionConfig": "NoEncryption"
                       },
                       "RoleARN": "delivery-stream-role",
                       "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket2",
                       "BufferingHints": {
                           "IntervalInSeconds": 300,
                           "SizeInMBs": 5
                       }
                   }
               }
           ]
       }
   }
   ```

1. Firehose 전송 스트림으로 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 텍스트 편집기를 사용하여 `~/TrustPolicyForCWL.json` 파일에 신뢰 정책을 생성합니다.

   이 정책에는 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키가 포함되어 있습니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 섹션을 참조하세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole",
       "Condition": { 
            "StringLike": { 
                "aws:SourceArn": "arn:aws:logs:region:123456789012:*"
            } 
        }
     }
   }
   ```

1. **create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이후 단계에서 필요할 수 있기 때문에 반환된 **Role.Arn** 값을 적어둡니다.

   ```
   aws iam create-role \
   --role-name CWLtoKinesisFirehoseRole \
   --assume-role-policy-document file://~/TrustPolicyForCWL.json
   
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   },
                   "Condition": { 
                        "StringLike": { 
                            "aws:SourceArn": "arn:aws:logs:region:123456789012:*"
                        } 
                    }
               }
           },
           "RoleId": "AAOIIAH450GAB4HC5F431",
           "CreateDate": "2015-05-29T13:46:29.431Z",
           "RoleName": "CWLtoKinesisFirehoseRole",
           "Path": "/",
           "Arn": "arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole"
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 권한 정책을 파일로 생성합니다(예: `~/PermissionsForCWL.json`).

   ```
   {
       "Statement":[
         {
           "Effect":"Allow",
           "Action":["firehose:PutRecord"],
           "Resource":[
               "arn:aws:firehose:region:account-id:deliverystream/delivery-stream-name"]
         }
       ]
   }
   ```

1. put-role-policy 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy --role-name CWLtoKinesisFirehoseRole --policy-name Permissions-Policy-For-CWL --policy-document file://~/PermissionsForCWL.json
   ```

1. Amazon Data Firehose 전송 스트림이 활성 상태가 되고 IAM 역할을 생성하고 나면 CloudWatch Logs 구독 필터를 생성할 수 있습니다. 그 즉시 구독 필터는 실시간으로 선택한 로그 그룹에서 Amazon Data Firehose 전송 스트림으로 로그 데이터를 이동시키기 시작합니다.

   ```
   aws logs put-subscription-filter \
       --log-group-name "CloudTrail" \
       --filter-name "Destination" \
       --filter-pattern "{$.userIdentity.type = Root}" \
       --destination-arn "arn:aws:firehose:region:123456789012:deliverystream/my-delivery-stream" \
       --role-arn "arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole"
   ```

1. 구독 필터를 설정하고 나면 CloudWatch Logs는 모든 수신 로그 이벤트 중에서 필터 패턴과 일치하는 이벤트를 Amazon Data Firehose 전송 스트림으로 전달합니다. Amazon Data Firehose 전송 스트림에 설정된 시간 버퍼 간격에 따라 Amazon S3에 데이터가 나타나기 시작합니다. 충분한 시간이 지나고 나면 Amazon S3 버킷을 확인하여 데이터를 확인할 수 있습니다.

   ```
   aws s3api list-objects --bucket 'amzn-s3-demo-bucket2' --prefix 'firehose/'
   {
       "Contents": [
           {
               "LastModified": "2015-10-29T00:01:25.000Z",
               "ETag": "\"a14589f8897f4089d3264d9e2d1f1610\"",
               "StorageClass": "STANDARD",
               "Key": "firehose/2015/10/29/00/my-delivery-stream-2015-10-29-00-01-21-a188030a-62d2-49e6-b7c2-b11f1a7ba250",
               "Owner": {
                   "DisplayName": "cloudwatch-logs",
                   "ID": "1ec9cf700ef6be062b19584e0b7d84ecc19237f87b5"
               },
               "Size": 593
           },
           {
               "LastModified": "2015-10-29T00:35:41.000Z",
               "ETag": "\"a7035b65872bb2161388ffb63dd1aec5\"",
               "StorageClass": "STANDARD",
               "Key": "firehose/2015/10/29/00/my-delivery-stream-2015-10-29-00-35-40-7cc92023-7e66-49bc-9fd4-fc9819cc8ed3",
               "Owner": {
                   "DisplayName": "cloudwatch-logs",
                   "ID": "1ec9cf700ef6be062b19584e0b7d84ecc19237f87b6"
               },
               "Size": 5752
           }
       ]
   }
   ```

   ```
   aws s3api get-object --bucket 'amzn-s3-demo-bucket2' --key 'firehose/2015/10/29/00/my-delivery-stream-2015-10-29-00-01-21-a188030a-62d2-49e6-b7c2-b11f1a7ba250' testfile.gz
   
   {
       "AcceptRanges": "bytes",
       "ContentType": "application/octet-stream",
       "LastModified": "Thu, 29 Oct 2015 00:07:06 GMT",
       "ContentLength": 593,
       "Metadata": {}
   }
   ```

   Amazon S3 객체의 데이터는 gzip 형식으로 압축됩니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

   ```
   zcat testfile.gz
   ```

## 예제 4: Amazon OpenSearch Service를 사용한 구독 필터
<a name="OpenSearchExample"></a>

이 예제에서는 정의된 필터와 일치하는 수신 로그 이벤트를 OpenSearch Service 도메인으로 전송하는 CloudWatch Logs 구독을 생성합니다.

**OpenSearch Service에 구독 필터를 생성하려면**

1. OpenSearch Service 도메인을 생성합니다. 자세한 내용은 [Creating OpenSearch Service domains](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/createupdatedomains.html#createdomains)을 참조하세요.

1. [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)에서 CloudWatch 콘솔을 엽니다.

1.  탐색 창에서 **로그 그룹**을 선택합니다.

1. 로그 그룹의 이름을 선택합니다.

1. **작업**, **구독 필터**, **Amazon OpenSearch Service 구독 필터 생성**을 선택합니다.

1. 이 계정의 클러스터로 스트리밍하려고 하는지 아니면 다른 계정의 클러스터로 스트리밍하려고 하는지 선택합니다.
   + **이 계정**을 선택한 경우 1단계에서 생성된 도메인을 선택합니다.
   + **다른 계정**을 선택한 경우 해당 도메인의 ARN 및 엔드포인트를 입력합니다.

1.  다른 계정을 선택한 경우 도메인 ARN 및 엔드포인트를 제공합니다.

1. Amazon OpenSearch Service 클러스터에서 로그 그룹 데이터가 전달될 클러스터의 이름을 선택합니다.

1. 로그 형식을 선택합니다.

1. **구독 필터 패턴**에 로그 이벤트에서 찾을 용어나 패턴을 입력합니다. 이렇게 하면 관심 있는 데이터만 OpenSearch Service 클러스터로 전송할 수 있습니다. 자세한 내용은 [지표 필터에 대한 필터 패턴 구문](FilterAndPatternSyntaxForMetricFilters.md) 단원을 참조하십시오.

1. (선택 사항) **테스트할 로그 데이터 선택**에서 로그 스트림을 선택한 다음 **패턴 테스트**를 선택해서 검색 필터가 예상한 결과를 반환하고 있는지 확인합니다.

1. **스트리밍 시작**을 선택합니다.

# 계정 수준 구독 필터
<a name="SubscriptionFilters-AccountLevel"></a>

**중요**  
구독 필터는 무한 재귀 루프를 발생시킬 위험이 있으며, 이를 해결하지 않으면 수집 요금 청구가 크게 증가할 수 있습니다. 이러한 위험을 완화하려면 계정 수준 구독 필터에서 선택 기준을 사용하여 구독 전송 워크플로의 일부인 리소스에서 로그 데이터를 수집하는 로그 그룹을 제외하는 것이 좋습니다. 이 문제 및 제외할 로그 그룹 결정에 대한 자세한 내용은 [로그 재귀 방지](Subscriptions-recursion-prevention.md)을 참조하세요.

 계정의 로그 그룹 하위 집합을 포함하는 계정 수준 구독 정책을 설정할 수 있습니다. 계정 구독 정책은 Amazon Kinesis Data Streams AWS Lambda또는 Amazon Data Firehose에서 작동할 수 있습니다. 계정 수준 구독 정책을 통해 서비스로 전송되는 로그는 base64로 인코딩되고 gzip 형식으로 압축됩니다. 이 섹션에서는 Amazon Kinesis Data Streams, Lambda 및 Firehose에 대한 계정 수준 구독을 생성하기 위해 따를 수 있는 예제를 제공합니다.

**참고**  
계정의 모든 구독 필터 정책 목록을 확인하려면 `--policy-type` 파라미터 값 `SUBSCRIPTION_FILTER_POLICY`를 사용하여 `describe-account-policies` 명령을 사용합니다. 자세한 내용은 [ describe-account-policies¶](https://docs.aws.amazon.com/cli/latest/reference/logs/describe-account-policies.html)를 참조하세요.

**Topics**
+ [예제 1: Amazon Kinesis Data Streams를 사용한 구독 필터](#DestinationKinesisExample-AccountLevel)
+ [예제 2:를 사용한 구독 필터 AWS Lambda](#LambdaFunctionExample-AccountLevel)
+ [예제 3: Amazon Data Firehose에 대한 구독 필터](#FirehoseExample-AccountLevel)

## 예제 1: Amazon Kinesis Data Streams를 사용한 구독 필터
<a name="DestinationKinesisExample-AccountLevel"></a>

계정 수준 구독 정책과 함께 사용할 Amazon Kinesis Data Streams 데이터 스트림을 생성하기 전에 생성될 로그 데이터의 볼륨을 계산합니다. 이 볼륨을 처리하기에 충분한 샤드로 스트림을 생성해야 합니다. 스트림에 샤드가 충분하지 않은 경우 스트림에 스로틀링이 발생합니다. 스트림 볼륨 제한에 대한 자세한 내용은 Amazon Kinesis Data Streams 설명서의 [ 할당량 및 제한을](https://docs.aws.amazon.com/streams/latest/dev/service-sizes-and-limits.html) 참조하세요.

**주의**  
여러 로그 그룹의 로그 이벤트가 대상에 전달되므로 스로틀링의 위험이 있습니다. 스로틀링이 발생한 전송물은 최대 24시간 동안 재시도됩니다. 24시간이 지나면 실패한 결과물이 삭제됩니다.  
스로틀링 현상의 위험을 완화하려면 다음 단계를 수행합니다.  
CloudWatch 지표를 사용하여 Amazon Kinesis Data Streams 스트림을 모니터링합니다. 이렇게 하면 스로틀링 현상을 식별하며, 이에 따라 구성을 조정할 수 있습니다. 예를 들어 `DeliveryThrottling` 지표는 데이터를 구독 대상에 전달할 때 CloudWatch Logs에 스로틀링이 발생한 로그 이벤트 수를 추적합니다. 자세한 내용은 [CloudWatch 지표를 사용한 모니터링](CloudWatch-Logs-Monitoring-CloudWatch-Metrics.md) 단원을 참조하십시오.
Amazon Kinesis Data Streams에서 스트림에 대한 온디맨드 용량 모드를 사용합니다. 온디맨드 모드는 워크로드가 확장 또는 축소될 때 즉시 워크로드를 수용합니다. 자세한 내용은 [ 온디맨드 모드](https://docs.aws.amazon.com/streams/latest/dev/how-do-i-size-a-stream.html#ondemandmode)를 참조하세요.
CloudWatch Logs 구독 필터 패턴을 Amazon Kinesis Data Streams의 스트림 용량과 일치하도록 제한합니다. 스트림에 너무 많은 데이터를 전송하는 경우 필터 크기를 줄이거나 필터 기준을 조정해야 할 수 있습니다.

다음 예제에서는 계정 수준 구독 정책을 사용하여 모든 로그 이벤트를 Amazon Kinesis Data Streams의 스트림으로 전달합니다. 필터 패턴은 모든 로그 이벤트를 텍스트와 일치`Test`시키고 Amazon Kinesis Data Streams의 스트림으로 전달합니다.

**Amazon Kinesis Data Streams에 대한 계정 수준 구독 정책을 생성하려면**

1. 다음 명령을 사용하여 대상 스트림을 생성합니다.

   ```
   $ C:\>  aws kinesis create-stream —stream-name "TestStream" —shard-count 1
   ```

1. 스트림이 활성화될 때까지 몇 분 정도 기다립니다. [describe-stream](https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html) 명령을 사용하여 **StreamDescription.StreamStatus** 속성을 확인하면 스트림이 활성인지 여부를 확인할 수 있습니다.

   ```
   aws kinesis describe-stream --stream-name "TestStream"
   ```

   다음은 예제 출력입니다.

   ```
   {
       "StreamDescription": {
           "StreamStatus": "ACTIVE",
           "StreamName": "TestStream",
           "StreamARN": "arn:aws:kinesis:region:123456789012:stream/TestStream",
           "Shards": [
               {
                   "ShardId": "shardId-000000000000",
                   "HashKeyRange": {
                       "EndingHashKey": "EXAMPLE8463463374607431768211455",
                       "StartingHashKey": "0"
                   },
                   "SequenceNumberRange": {
                       "StartingSequenceNumber":
                       "EXAMPLE688818456679503831981458784591352702181572610"
                   }
               }
           ]
       }
   }
   ```

1. 스트림에 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 신뢰 정책을 파일로 생성해야 합니다(예: `~/TrustPolicyForCWL-Kinesis.json`). 텍스트 편집기를 사용하여 이 정책을 생성합니다.

   이 정책에는 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키가 포함되어 있습니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 섹션을 참조하세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole",
       "Condition": { 
           "StringLike": { "aws:SourceArn": "arn:aws:logs:region:123456789012:*" } 
        }
      }
   }
   ```

1. **create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이후 단계에서 필요할 수 있기 때문에 반환된 **Role.Arn** 값을 적어둡니다.

   ```
   aws iam create-role --role-name CWLtoKinesisRole --assume-role-policy-document file://~/TrustPolicyForCWL-Kinesis.json
   ```

   다음은 출력의 예제입니다.

   ```
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   },
                   "Condition": { 
                       "StringLike": { 
                           "aws:SourceArn": { "arn:aws:logs:region:123456789012:*" }
                       } 
                   }
               }
           },
           "RoleId": "EXAMPLE450GAB4HC5F431",
           "CreateDate": "2023-05-29T13:46:29.431Z",
           "RoleName": "CWLtoKinesisRole",
           "Path": "/",
           "Arn": "arn:aws:iam::123456789012:role/CWLtoKinesisRole"
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 파일에 권한 정책을 생성합니다(예: `~/PermissionsForCWL-Kinesis.json`). 텍스트 편집기를 사용하여 이 정책을 생성합니다. IAM 콘솔을 사용하여 정책을 생성하지 마세요.

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "kinesis:PutRecord",
         "Resource": "arn:aws:kinesis:region:123456789012:stream/TestStream"
       }
     ]
   }
   ```

1. 다음 [put-role-policy](https://docs.aws.amazon.com/cli/latest/reference/iam/put-role-policy.html) 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy  --role-name CWLtoKinesisRole  --policy-name Permissions-Policy-For-CWL  --policy-document file://~/PermissionsForCWL-Kinesis.json
   ```

1. 스트림이 **Active** 상태에 있고 IAM 역할을 생성하고 나면 CloudWatch Logs 구독 필터 정책을 생성할 수 있습니다. 이 정책은 스트림으로 가는 실시간 로그 데이터 흐름을 즉시 시작합니다. 이 예제에서는 `LogGroupToExclude1`과 `LogGroupToExclude2`라는 로그 그룹의 이벤트를 제외하고 `ERROR` 문자열을 포함하는 모든 로그 이벤트가 스트리밍됩니다.

   ```
   aws logs put-account-policy \
       --policy-name "ExamplePolicy" \
       --policy-type "SUBSCRIPTION_FILTER_POLICY" \
       --policy-document '{"RoleArn":"arn:aws:iam::123456789012:role/CWLtoKinesisRole", "DestinationArn":"arn:aws:kinesis:region:123456789012:stream/TestStream", "FilterPattern": "Test", "Distribution": "Random"}' \
       --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
       --scope "ALL"
   ```

1. 구독 필터를 설정하고 나면 CloudWatch Logs는 모든 수신 로그 이벤트 중에서 필터 패턴 및 선택 기준과 일치하는 이벤트를 스트림으로 전달합니다.

   `selection-criteria` 필드는 선택 사항이지만 구독 필터에서 무한 로그 재귀를 일으킬 수 있는 로그 그룹을 제외하는 데 중요합니다. 이 문제 및 제외할 로그 그룹 결정에 대한 자세한 내용은 [로그 재귀 방지](Subscriptions-recursion-prevention.md)을 참조하세요. 현재 NOT IN은 `selection-criteria`에 지원되는 유일한 연산자입니다.

   Amazon Kinesis Data Streams 샤드 반복기를 사용하고 Amazon Kinesis Data Streams `get-records` 명령을 사용하여 일부 Amazon Kinesis Data Streams 레코드를 가져와 로그 이벤트의 흐름을 확인할 수 있습니다.

   ```
   aws kinesis get-shard-iterator --stream-name TestStream --shard-id shardId-000000000000 --shard-iterator-type TRIM_HORIZON
   ```

   ```
   {
       "ShardIterator":
       "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiK2OSh0uP"
   }
   ```

   ```
   aws kinesis get-records --limit 10 --shard-iterator "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiK2OSh0uP"
   ```

   Amazon Kinesis Data Streams가 데이터를 반환하기 전에이 명령을 몇 번 사용해야 할 수 있습니다.

   레코드 어레이에서 응답을 확인할 수 있습니다. Amazon Kinesis **Data** Streams 레코드의 데이터 속성은 base64로 인코딩되고 gzip 형식으로 압축됩니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

   ```
   echo -n "<Content of Data>" | base64 -d | zcat
   ```

   디코딩 및 압축 해제된 base64 데이터는 다음 구조를 가진 JSON으로 포맷됩니다.

   ```
   { 
       "messageType": "DATA_MESSAGE",
       "owner": "123456789012",
       "logGroup": "Example1",
       "logStream": "logStream1",
       "subscriptionFilters": [ 
           "ExamplePolicy" 
       ],
       "logEvents": [ 
           { 
               "id": "31953106606966983378809025079804211143289615424298221568",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           },
           { 
               "id": "31953106606966983378809025079804211143289615424298221569",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" 
           }, 
           { 
               "id": "31953106606966983378809025079804211143289615424298221570",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" 
           } 
       ],
       "policyLevel": "ACCOUNT_LEVEL_POLICY"
   }
   ```

   데이터 구조에서 키 요소는 다음과 같습니다.  
**messageType**  
데이터 메시지는 'DATA\$1MESSAGE' 유형을 사용합니다. CloudWatch Logs는 주로 대상에 연결할 수 있는지 확인하기 위해 "CONTROL\$1MESSAGE" 유형의 Amazon Kinesis Data Streams 레코드를 내보낼 수 있습니다.  
**owner**  
원본 로그 데이터의 AWS 계정 ID입니다.  
**logGroup**  
원본 로그 데이터의 로그 그룹 이름.  
**logStream**  
원본 로그 데이터의 로그 스트림 이름.  
**subscriptionFilters**  
원본 로그 데이터과 일치한 구독 필터 이름 목록입니다.  
**logEvents**  
로그 이벤트 레코드의 배열로 표현되는 실제 로그 데이터. 'ID' 속성은 모든 로그 이벤트의 고유 식별자입니다.  
**policyLevel**  
정책이 적용된 수준. 'ACCOUNT\$1LEVEL\$1POLICY'는 계정 수준 구독 필터 정책의 `policyLevel`입니다.

## 예제 2:를 사용한 구독 필터 AWS Lambda
<a name="LambdaFunctionExample-AccountLevel"></a>

이 예제에서는 로그 데이터를 AWS Lambda 함수로 전송하는 CloudWatch Logs 계정 수준 구독 필터 정책을 생성합니다.

**주의**  
Lambda 함수를 생성하기 전에 생성할 로그 데이터의 볼륨을 계산합니다. 이 볼륨을 처리할 수 있는 함수를 생성해야 합니다. 함수가 볼륨을 처리할 수 없는 경우 로그 스트림에 스로틀링이 발생합니다. 모든 로그 그룹 또는 계정 로그 그룹의 하위 집합의 로그 이벤트가 대상으로 전달되므로 스로틀링의 위험이 있습니다. [AWS Lambda 제한 사항](https://docs.aws.amazon.com/lambda/latest/dg/limits.html)에 대한 자세한 내용은 Lambda 제한 사항을 참조하세요.

**Lambda의 계정 수준 구독 필터 정책을 생성하려면**

1.  AWS Lambda 함수를 생성합니다.

   Lambda 실행 역할이 설정되었는지 확인합니다. 자세한 내용은 *AWS Lambda Developer Guide*의 [Step 2.2: Create an IAM Role (execution role)](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)을 참조하세요.

1. 다음 콘텐츠로 텍스트 편집기를 열고 `helloWorld.js`라는 파일을 생성합니다.

   ```
   var zlib = require('zlib');
   exports.handler = function(input, context) {
       var payload = Buffer.from(input.awslogs.data, 'base64');
       zlib.gunzip(payload, function(e, result) {
           if (e) { 
               context.fail(e);
           } else {
               result = JSON.parse(result.toString());
               console.log("Event Data:", JSON.stringify(result, null, 2));
               context.succeed();
           }
       });
   };
   ```

1. helloWorld.js 파일을 압축하고 `helloWorld.zip`라는 이름으로 저장합니다.

1. 역할이 첫 단계에서 설정한 Lambda 실행 역할인 경우에는 다음 명령을 사용합니다.

   ```
   aws lambda create-function \
       --function-name helloworld \
       --zip-file fileb://file-path/helloWorld.zip \
       --role lambda-execution-role-arn \
       --handler helloWorld.handler \
       --runtime nodejs18.x
   ```

1. CloudWatch Logs에 함수를 실행할 권한을 부여합니다. 다음 명령을 사용하고 자리 표시자 계정을 자신의 계정으로 바꿉니다.

   ```
   aws lambda add-permission \
       --function-name "helloworld" \
       --statement-id "helloworld" \
       --principal "logs.amazonaws.com" \
       --action "lambda:InvokeFunction" \
       --source-arn "arn:aws:logs:region:123456789012:log-group:*" \
       --source-account "123456789012"
   ```

1. 다음 명령을 사용하고 자리 표시자 계정을 자신의 계정으로 바꾸어 계정 수준 구독 필터 정책을 생성합니다. 이 예제에서는 `LogGroupToExclude1`과 `LogGroupToExclude2`라는 로그 그룹의 이벤트를 제외하고 `ERROR` 문자열을 포함하는 모든 로그 이벤트가 스트리밍됩니다.

   ```
   aws logs put-account-policy \
       --policy-name "ExamplePolicyLambda" \
       --policy-type "SUBSCRIPTION_FILTER_POLICY" \
       --policy-document '{"DestinationArn":"arn:aws:lambda:region:123456789012:function:helloWorld", "FilterPattern": "Test", "Distribution": "Random"}' \
       --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
       --scope "ALL"
   ```

   구독 필터를 설정하고 나면 CloudWatch Logs는 모든 수신 로그 이벤트 중에서 필터 패턴 및 선택 기준과 일치하는 이벤트를 스트림으로 전달합니다.

   `selection-criteria` 필드는 선택 사항이지만 구독 필터에서 무한 로그 재귀를 일으킬 수 있는 로그 그룹을 제외하는 데 중요합니다. 이 문제 및 제외할 로그 그룹 결정에 대한 자세한 내용은 [로그 재귀 방지](Subscriptions-recursion-prevention.md)을 참조하세요. 현재 NOT IN은 `selection-criteria`에 지원되는 유일한 연산자입니다.

1. (선택 사항) 샘플 로그 이벤트를 사용하여 테스트합니다. 명령 프롬프트에서 다음 명령을 실행하여 구독된 스트림으로 간단한 로그 메시지를 보냅니다.

   Lambda 함수의 출력을 보려면 /aws/lambda/helloworld에 출력이 표시되는 Lambda 함수를 탐색합니다.

   ```
   aws logs put-log-events --log-group-name Example1 --log-stream-name logStream1 --log-events "[{\"timestamp\":CURRENT TIMESTAMP MILLIS , \"message\": \"Simple Lambda Test\"}]"
   ```

   Lambda의 배열로 응답을 확인할 수 있습니다. Lambda 레코드의 **데이터** 속성은 base64로 인코딩되고 gzip 형식으로 압축됩니다. Lambda가 수신하는 실제 페이로드는 `{ "awslogs": {"data": "BASE64ENCODED_GZIP_COMPRESSED_DATA"} }` 형식을 따릅니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

   ```
   echo -n "<BASE64ENCODED_GZIP_COMPRESSED_DATA>" | base64 -d | zcat
   ```

   디코딩 및 압축 해제된 base64 데이터는 다음 구조를 가진 JSON으로 포맷됩니다.

   ```
   { 
       "messageType": "DATA_MESSAGE",
       "owner": "123456789012",
       "logGroup": "Example1",
       "logStream": "logStream1",
       "subscriptionFilters": [ 
           "ExamplePolicyLambda" 
       ],
       "logEvents": [ 
           { 
               "id": "31953106606966983378809025079804211143289615424298221568",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
           },
           { 
               "id": "31953106606966983378809025079804211143289615424298221569",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" 
           }, 
           { 
               "id": "31953106606966983378809025079804211143289615424298221570",
               "timestamp": 1432826855000,
               "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" 
           } 
       ],
       "policyLevel": "ACCOUNT_LEVEL_POLICY"
   }
   ```
**참고**  
계정 수준 구독 필터는 대상 Lambda 함수의 로그 그룹에 적용되지 않습니다. 이는 수집 요금 청구를 증가시킬 수 있는 무한 로그 재귀를 방지하기 위한 것입니다. 이 문제에 대한 자세한 내용은 [로그 재귀 방지](Subscriptions-recursion-prevention.md)을 참조하세요.

   데이터 구조에서 키 요소는 다음과 같습니다.  
**messageType**  
데이터 메시지는 'DATA\$1MESSAGE' 유형을 사용합니다. CloudWatch Logs는 주로 대상에 연결할 수 있는지 확인하기 위해 "CONTROL\$1MESSAGE" 유형의 Amazon Kinesis Data Streams 레코드를 내보낼 수 있습니다.  
**owner**  
원본 로그 데이터의 AWS 계정 ID입니다.  
**logGroup**  
원본 로그 데이터의 로그 그룹 이름.  
**logStream**  
원본 로그 데이터의 로그 스트림 이름.  
**subscriptionFilters**  
원본 로그 데이터과 일치한 구독 필터 이름 목록입니다.  
**logEvents**  
로그 이벤트 레코드의 배열로 표현되는 실제 로그 데이터. 'ID' 속성은 모든 로그 이벤트의 고유 식별자입니다.  
**policyLevel**  
정책이 적용된 수준. “ACCOUNT\$1LEVEL\$1POLICY”는 계정 수준 구독 필터 정책의 `policyLevel`입니다.

## 예제 3: Amazon Data Firehose에 대한 구독 필터
<a name="FirehoseExample-AccountLevel"></a>

이 예제에서는 수신 로그 이벤트 중에서 정의된 필터와 일치하는 이벤트를 Amazon Data Firehose 전송 스트림에 전송하는 CloudWatch Logs 계정 수준 구독 필터 정책을 생성합니다. CloudWatch Logs에서 Amazon Data Firehose로 전송된 데이터는 이미 gzip 6 수준의 압축이 되었기 때문에 Firehose 전송 스트림 내에서 압축을 사용할 필요가 없습니다. 그런 다음 Firehose의 압축 해제 기능을 사용하여 로그를 자동으로 압축 해제할 수 있습니다. 자세한 내용은 [ CloudWatch Logs를 사용하여 Kinesis Data Firehose에 쓰기](https://docs.aws.amazon.com/firehose/latest/dev/writing-with-cloudwatch-logs.html)를 참조하세요.

**주의**  
Firehose 스트림을 생성하기 전에 생성될 로그 데이터의 볼륨을 계산합니다. 이 볼륨을 처리할 수 있는 Firehose 스트림을 생성해야 합니다. 스트림이 볼륨을 처리할 수 없는 경우 로그 스트림에 스로틀링이 발생합니다. Firehose 스트림 볼륨 제한 사항에 대한 자세한 내용은 [Amazon Data Firehose 데이터 제한 사항](https://docs.aws.amazon.com/firehose/latest/dev/limits.html)을 참조하세요.

**Firehose 구독 필터를 생성하려면**

1. Amazon Simple Storage Service(Amazon S3) 버킷을 생성합니다. CloudWatch Logs를 위해 특별히 생성한 버킷을 사용하는 것이 좋습니다. 그러나 기존 버킷을 사용하고 싶으면 2단계로 건너뛸 수 있습니다.

   다음 명령을 실행하여 자리 표시자 리전을 사용하고자 하는 리전으로 바꿉니다.

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-bucket2 --create-bucket-configuration LocationConstraint=region
   ```

   다음은 예제 출력입니다.

   ```
   {
       "Location": "/amzn-s3-demo-bucket2"
   }
   ```

1. Amazon S3 버킷에 데이터를 입력하는 데 필요한 권한을 Amazon Data Firehose에 부여하는 IAM 역할을 생성합니다.

   자세한 내용은 *Amazon Data Firehose 개발자 가이드*의 [Amazon Data Firehose를 사용하여 액세스 제어](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html)를 참조하세요.

   먼저 텍스트 편집기를 사용하여 다음과 같이 `~/TrustPolicyForFirehose.json` 파일에 신뢰 정책을 생성합니다.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "firehose.amazonaws.com" },
       "Action": "sts:AssumeRole"
       } 
   }
   ```

1. **create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이후 단계에서 필요하므로 반환된 **Role.Arn** 값을 적어둡니다.

   ```
   aws iam create-role \
    --role-name FirehosetoS3Role \
    --assume-role-policy-document file://~/TrustPolicyForFirehose.json
   
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "firehose.amazonaws.com"
                   }
               }
           },
           "RoleId": "EXAMPLE50GAB4HC5F431",
           "CreateDate": "2023-05-29T13:46:29.431Z",
           "RoleName": "FirehosetoS3Role",
           "Path": "/",
           "Arn": "arn:aws:iam::123456789012:role/FirehosetoS3Role"
       }
   }
   ```

1. Firehose가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 `~/PermissionsForFirehose.json` 파일엣 권한 정책을 생성합니다.

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [ 
             "s3:AbortMultipartUpload", 
             "s3:GetBucketLocation", 
             "s3:GetObject", 
             "s3:ListBucket", 
             "s3:ListBucketMultipartUploads", 
             "s3:PutObject" ],
         "Resource": [ 
             "arn:aws:s3:::amzn-s3-demo-bucket2", 
             "arn:aws:s3:::amzn-s3-demo-bucket2/*" ]
       }
     ]
   }
   ```

1. 다음 put-role-policy 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy --role-name FirehosetoS3Role --policy-name Permissions-Policy-For-Firehose --policy-document file://~/PermissionsForFirehose.json
   ```

1. 다음과 같이 대상 Firehose 전송 시스템을 생성하여 **RoleARN** 및 **BucketARN**의 자리 표시자 값을 생성한 역할 및 버킷 ARN으로 바꿉니다.

   ```
   aws firehose create-delivery-stream \
      --delivery-stream-name 'my-delivery-stream' \
      --s3-destination-configuration \
     '{"RoleARN": "arn:aws:iam::123456789012:role/FirehosetoS3Role", "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket2"}'
   ```

   Firehose는 제공된 Amazon S3 객체에서 YYYY/MM/DD/HH UTC 시간 형식의 접두사를 자동으로 사용합니다. 시간 형식 접두사 앞에 추가할 또 다른 접두사를 지정할 수 있습니다. 슬래시(/)로 끝난 접두사는 Amazon S3 버킷에서 폴더로 표시됩니다.

1. 스트림이 활성화될 때까지 몇 분 정도 기다립니다. Firehose **describe-delivery-stream** 명령을 사용하여 **DeliveryStreamDescription.DeliveryStreamStatus** 속성을 확인할 수 있습니다. 또한 이후 단계에서 필요할 수 있기 때문에 **DeliveryStreamDescription.DeliveryStreamARN** 값을 적어둡니다.

   ```
   aws firehose describe-delivery-stream --delivery-stream-name "my-delivery-stream"
   {
       "DeliveryStreamDescription": {
           "HasMoreDestinations": false,
           "VersionId": "1",
           "CreateTimestamp": 1446075815.822,
           "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789012:deliverystream/my-delivery-stream",
           "DeliveryStreamStatus": "ACTIVE",
           "DeliveryStreamName": "my-delivery-stream",
           "Destinations": [
               {
                   "DestinationId": "destinationId-000000000001",
                   "S3DestinationDescription": {
                       "CompressionFormat": "UNCOMPRESSED",
                       "EncryptionConfiguration": {
                           "NoEncryptionConfig": "NoEncryption"
                       },
                       "RoleARN": "delivery-stream-role",
                       "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket2",
                       "BufferingHints": {
                           "IntervalInSeconds": 300,
                           "SizeInMBs": 5
                       }
                   }
               }
           ]
       }
   }
   ```

1. Firehose 전송 스트림으로 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 텍스트 편집기를 사용하여 `~/TrustPolicyForCWL.json` 파일에 신뢰 정책을 생성합니다.

   이 정책에는 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키가 포함되어 있습니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 섹션을 참조하세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole",
       "Condition": { 
            "StringLike": { 
                "aws:SourceArn": "arn:aws:logs:region:123456789012:*"
            } 
        }
     }
   }
   ```

1. **create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이후 단계에서 필요하므로 반환된 **Role.Arn** 값을 적어둡니다.

   ```
   aws iam create-role \
   --role-name CWLtoKinesisFirehoseRole \
   --assume-role-policy-document file://~/TrustPolicyForCWL.json
   
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   },
                   "Condition": { 
                        "StringLike": { 
                            "aws:SourceArn": "arn:aws:logs:region:123456789012:*"
                        } 
                    }
               }
           },
           "RoleId": "AAOIIAH450GAB4HC5F431",
           "CreateDate": "2015-05-29T13:46:29.431Z",
           "RoleName": "CWLtoKinesisFirehoseRole",
           "Path": "/",
           "Arn": "arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole"
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 권한 정책을 파일로 생성합니다(예: `~/PermissionsForCWL.json`).

   ```
   {
       "Statement":[
         {
           "Effect":"Allow",
           "Action":["firehose:PutRecord"],
           "Resource":[
               "arn:aws:firehose:region:account-id:deliverystream/delivery-stream-name"]
         }
       ]
   }
   ```

1. put-role-policy 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy --role-name CWLtoKinesisFirehoseRole --policy-name Permissions-Policy-For-CWL --policy-document file://~/PermissionsForCWL.json
   ```

1. Amazon Data Firehose 전송 스트림이 활성 상태가 되고 IAM 역할을 생성하고 나면 CloudWatch Logs 계정 수준 구독 필터 정책을 생성할 수 있습니다. 그 즉시 정책은 선택한 로그 그룹에서 Amazon Data Firehose 전송 스트림으로 실시간 로그 데이터 흐름을 시작합니다.

   ```
   aws logs put-account-policy \
       --policy-name "ExamplePolicyFirehose" \
       --policy-type "SUBSCRIPTION_FILTER_POLICY" \
       --policy-document '{"RoleArn":"arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole", "DestinationArn":"arn:aws:firehose:us-east-1:123456789012:deliverystream/delivery-stream-name", "FilterPattern": "Test", "Distribution": "Random"}' \
       --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
       --scope "ALL"
   ```

1. 구독 필터를 설정하고 나면 CloudWatch Logs는 수신 로그 이벤트 중에서 필터 패턴과 일치하는 이벤트를 Amazon Data Firehose 전송 스트림으로 전달합니다.

   `selection-criteria` 필드는 선택 사항이지만 구독 필터에서 무한 로그 재귀를 일으킬 수 있는 로그 그룹을 제외하는 데 중요합니다. 이 문제 및 제외할 로그 그룹 결정에 대한 자세한 내용은 [로그 재귀 방지](Subscriptions-recursion-prevention.md)을 참조하세요. 현재 NOT IN은 `selection-criteria`에 지원되는 유일한 연산자입니다.

   Amazon Data Firehose 전송 스트림에 설정된 시간 버퍼 간격에 따라 Amazon S3에 데이터가 나타나기 시작합니다. 충분한 시간이 지나고 나면 Amazon S3 버킷을 확인하여 데이터를 확인할 수 있습니다.

   ```
   aws s3api list-objects --bucket 'amzn-s3-demo-bucket2' --prefix 'firehose/'
   {
       "Contents": [
           {
               "LastModified": "2023-10-29T00:01:25.000Z",
               "ETag": "\"a14589f8897f4089d3264d9e2d1f1610\"",
               "StorageClass": "STANDARD",
               "Key": "firehose/2015/10/29/00/my-delivery-stream-2015-10-29-00-01-21-a188030a-62d2-49e6-b7c2-b11f1a7ba250",
               "Owner": {
                   "DisplayName": "cloudwatch-logs",
                   "ID": "1ec9cf700ef6be062b19584e0b7d84ecc19237f87b5"
               },
               "Size": 593
           },
           {
               "LastModified": "2015-10-29T00:35:41.000Z",
               "ETag": "\"a7035b65872bb2161388ffb63dd1aec5\"",
               "StorageClass": "STANDARD",
               "Key": "firehose/2023/10/29/00/my-delivery-stream-2023-10-29-00-35-40-EXAMPLE-7e66-49bc-9fd4-fc9819cc8ed3",
               "Owner": {
                   "DisplayName": "cloudwatch-logs",
                   "ID": "EXAMPLE6be062b19584e0b7d84ecc19237f87b6"
               },
               "Size": 5752
           }
       ]
   }
   ```

   ```
   aws s3api get-object --bucket 'amzn-s3-demo-bucket2' --key 'firehose/2023/10/29/00/my-delivery-stream-2023-10-29-00-01-21-a188030a-62d2-49e6-b7c2-b11f1a7ba250' testfile.gz
   
   {
       "AcceptRanges": "bytes",
       "ContentType": "application/octet-stream",
       "LastModified": "Thu, 29 Oct 2023 00:07:06 GMT",
       "ContentLength": 593,
       "Metadata": {}
   }
   ```

   Amazon S3 객체의 데이터는 gzip 형식으로 압축됩니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

   ```
   zcat testfile.gz
   ```

# 교차 계정 교차 리전 구독
<a name="CrossAccountSubscriptions"></a>

다른 AWS 계정의 소유자와 협업하고 Amazon Kinesis 또는 Amazon Data Firehose 스트림(이를 교차 계정 데이터 공유라고 함)과 같은 AWS 리소스에서 로그 이벤트를 수신할 수 있습니다. 예를 들어이 로그 이벤트 데이터는 중앙 집중식 Amazon Kinesis Data Streams 또는 Firehose 스트림에서 읽어 사용자 지정 처리 및 분석을 수행할 수 있습니다. 사용자 지정 처리는 특히 다수의 계정에서 데이터를 공동 사용 및 분석할 때 유용합니다.

예를 들어, 기업의 정보 보안 그룹은 실시간 침입 탐지나 이상 행동에 대한 데이터를 분석하고자 중앙 처리를 위해 연동된 프로덕션 로그를 수집하여 모든 부서의 계정에 대해 감사를 실시할 수 있습니다. Amazon Kinesis Data Streams를 사용하여 기존 보안 분석 시스템에 데이터를 연결할 수 있는 정보 보안 그룹에 이러한 계정 전반의 실시간 이벤트 데이터 스트림을 수집하여 전송할 수 있습니다.

**참고**  
로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상이 가리키는 AWS 리소스는 다른 리전에 위치할 수 있습니다. 다음 섹션의 예제에서는 모든 리전 관련 리소스가 미국 동부(버지니아 북부)에서 생성됩니다.

를 구성 AWS Organizations 하고 멤버 계정으로 작업하는 경우 로그 중앙 집중화를 사용하여 소스 계정에서 중앙 모니터링 계정으로 로그 데이터를 수집할 수 있습니다.

중앙 집중식 로그 그룹으로 작업할 때 구독 필터를 생성할 때 다음 시스템 필드 차원을 사용할 수 있습니다.
+ `@aws.account` -이 차원은 로그 이벤트가 시작된 AWS 계정 ID를 나타냅니다.
+ `@aws.region` -이 차원은 로그 이벤트가 생성된 AWS 리전을 나타냅니다.

이러한 차원은 로그 데이터의 소스를 식별하는 데 도움이 되므로 중앙 집중식 로그에서 파생된 지표를 보다 세부적으로 필터링하고 분석할 수 있습니다.

**Topics**
+ [Amazon Kinesis Data Streams를 사용한 교차 계정 교차 리전 로그 데이터 공유](CrossAccountSubscriptions-Kinesis.md)
+ [Firehose를 사용한 교차 계정 교차 리전 로그 데이터 공유](CrossAccountSubscriptions-Firehose.md)
+ [Amazon Kinesis Data Streams를 사용한 교차 계정 교차 리전 계정 수준 구독](CrossAccountSubscriptions-Kinesis-Account.md)
+ [Firehose를 사용한 교차 계정 교차 리전 계정 수준 구독](CrossAccountSubscriptions-Firehose-Account.md)

# Amazon Kinesis Data Streams를 사용한 교차 계정 교차 리전 로그 데이터 공유
<a name="CrossAccountSubscriptions-Kinesis"></a>

교차 계정 구독을 생성할 때 단일 계정 또는 조직을 발신자로 지정할 수 있습니다. 조직을 지정하는 경우 이 절차를 통해 조직의 모든 계정에서 수신자 계정으로 로그를 보낼 수 있습니다.

계정에서 로그 데이터를 공유하려면 로그 데이터 발신자 및 수신자를 설정해야 합니다.
+ **로그 데이터 발신자** - 수신자로부터 대상 정보를 얻고 지정된 대상으로 로그 이벤트를 전송할 준비가 되었음을 CloudWatch Logs에 알립니다. 이 섹션의 나머지 부분에서는 가상 AWS 계정 번호가 111111111111인 로그 데이터 발신자가 표시됩니다.

  한 조직 내의 여러 계정에서 한 수신자 계정으로 로그를 보내려면 해당 조직의 모든 계정에서 수신자 계정으로 로그를 보낼 수 있는 권한을 부여하는 정책을 만들 수 있습니다. 각 발신자 계정에 대해 별도의 구독 필터를 설정해야 합니다.
+ **로그 데이터 수신자** - Amazon Kinesis Data Streams 스트림을 캡슐화하는 대상을 설정하고 CloudWatch Logs에 수신자가 로그 데이터를 수신하고 싶다는 사실을 알립니다. 그런 다음 수신자는 이 대상에 대한 정보를 발신자와 공유합니다. 이 섹션의 나머지 부분에서는 로그 데이터 수신자가 가상 AWS 계정 번호 999999999999로 표시됩니다.

교차 계정 사용자로부터 로그 이벤트 수신을 시작하기 위해 로그 데이터 수신자는 먼저 CloudWatch Logs 대상을 생성합니다. 각 대상은 다음과 같은 키 요소로 이루어져 있습니다.

**대상 이름**  
생성하고자 하는 대상의 이름.

**대상 ARN**  
구독 피드의 대상으로 사용할 리소스의 Amazon AWS 리소스 이름(ARN)입니다.

**역할 ARN**  
CloudWatch Logs에 선택한 스트림에 데이터를 입력하는 데 필요한 권한을 부여하는 AWS Identity and Access Management (IAM) 역할입니다.

**액세스 정책**  
대상에 쓰기 권한이 허용된 사용자들에게 적용되는 IAM 정책 문서(JSON 형식, IAM 정책 문법을 사용해 작성)입니다.

**참고**  
로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상이 가리키는 AWS 리소스는 다른 리전에 위치할 수 있습니다. 다음 섹션의 예제에서는 모든 리전 관련 리소스가 미국 동부(버지니아 북부)에서 생성됩니다.

**Topics**
+ [새 교차 계정 구독 설정](Cross-Account-Log_Subscription-New.md)
+ [기존 교차 계정 구독 업데이트](Cross-Account-Log_Subscription-Update.md)

# 새 교차 계정 구독 설정
<a name="Cross-Account-Log_Subscription-New"></a>

이러한 섹션의 단계에 따라 새 교차 계정 로그 구독을 설정합니다.

**Topics**
+ [1단계: 대상 생성](CreateDestination.md)
+ [2단계: (조직을 사용하는 경우에만) IAM 역할 생성](CreateSubscriptionFilter-IAMrole.md)
+ [3단계: 교차 계정 대상에 대한 IAM 권한 추가/검증](Subscription-Filter-CrossAccount-Permissions.md)
+ [4단계: 구독 필터 생성](CreateSubscriptionFilter.md)
+ [로그 이벤트 흐름 검증](ValidateLogEventFlow.md)
+ [런타임 시 대상 멤버십 수정](ModifyDestinationMembership.md)

# 1단계: 대상 생성
<a name="CreateDestination"></a>

**중요**  
이 절차의 모든 단계는 로그 데이터 수신자 계정에서 수행되어야 합니다.

이 예제에서 로그 데이터 수신자 계정의 AWS 계정 ID는 999999999999이고 로그 데이터 발신자 AWS 계정 ID는 111111111111입니다.

 이 예제에서는 RecipientStream이라는 Amazon Kinesis Data Streams 스트림과 CloudWatch Logs가 데이터를 쓸 수 있는 역할을 사용하여 대상을 생성합니다.

대상이 생성되면 CloudWatch Logs는 수신자 계정을 대신하여 대상에게 테스트 메시지를 전송합니다. 구독 필터가 나중에 활성화되면 CloudWatch Logs는 소스 계정을 대신하여 대상에게 로그 이벤트를 보냅니다.

**대상을 생성하려면**

1. 수신자 계정에서 Amazon Kinesis Data Streams에 대상 스트림을 생성합니다. 명령 프롬프트에서 다음과 같이 입력합니다.

   ```
   aws kinesis create-stream --stream-name "RecipientStream" --shard-count 1
   ```

1. 스트림이 활성 상태가 될 때까지 기다립니다. **aws kinesis describe-stream** 명령을 사용하여 **StreamDescription.StreamStatus** 속성을 확인할 수 있습니다. 또한 CloudWatch Logs의 이후 단계에서 필요할 수 있기 때문에 **StreamDescription.StreamARN** 값을 기록해 둡니다.

   ```
   aws kinesis describe-stream --stream-name "RecipientStream"
   {
     "StreamDescription": {
       "StreamStatus": "ACTIVE",
       "StreamName": "RecipientStream",
       "StreamARN": "arn:aws:kinesis:us-east-1:999999999999:stream/RecipientStream",
       "Shards": [
         {
           "ShardId": "shardId-000000000000",
           "HashKeyRange": {
             "EndingHashKey": "34028236692093846346337460743176EXAMPLE",
             "StartingHashKey": "0"
           },
           "SequenceNumberRange": {
             "StartingSequenceNumber": "4955113521868881845667950383198145878459135270218EXAMPLE"
           }
         }
       ]
     }
   }
   ```

   스트림이 활성 상태가 될 때까지 1\$12분 정도 기다려야 할 수 있습니다.

1. 스트림에 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 **\$1/TrustPolicyForCWL.json** 파일에서 신뢰 정책을 생성해야 합니다. 텍스트 편집기를 사용하여 이 정책 파일을 생성하고 IAM 콘솔은 사용하지 마세요.

   이 정책은 `sourceAccountId`를 지정하여 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키를 포함합니다. 첫 번째 직접 호출에서 소스 계정 ID를 아직 모르는 경우 소스 ARN 필드에 대상 ARN을 넣는 것이 좋습니다. 후속 직접 호출에서는 소스 ARN을 첫 번째 직접 호출에서 수집한 실제 소스 ARN으로 설정해야 합니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 단원을 참조하십시오.

   ```
   {
       "Statement": {
           "Effect": "Allow",
           "Principal": {
               "Service": "logs.amazonaws.com"
           },
           "Condition": {
               "StringLike": {
                   "aws:SourceArn": [
                       "arn:aws:logs:region:sourceAccountId:*",
                       "arn:aws:logs:region:recipientAccountId:*"
                   ]
               }
           },
           "Action": "sts:AssumeRole"
       }
   }
   ```

1. **aws iam create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이 또한 CloudWatch Logs의 이후 단계에서 필요할 수 있기 때문에 반환된 Role.Arn 값을 적어 둡니다.

   ```
   aws iam create-role \
   --role-name CWLtoKinesisRole \
   --assume-role-policy-document file://~/TrustPolicyForCWL.json
   
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Condition": {
                       "StringLike": {
                           "aws:SourceArn": [
                               "arn:aws:logs:region:sourceAccountId:*",
                               "arn:aws:logs:region:recipientAccountId:*"
                           ]
                       }
                   },
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   }
               }
           },
           "RoleId": "AAOIIAH450GAB4HC5F431",
           "CreateDate": "2015-05-29T13:46:29.431Z",
           "RoleName": "CWLtoKinesisRole",
           "Path": "/",
           "Arn": "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 권한 정책을 **\$1/PermissionsForCWL.json** 파일로 생성합니다.

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "kinesis:PutRecord",
         "Resource": "arn:aws:kinesis:region:999999999999:stream/RecipientStream"
       }
     ]
   }
   ```

1. **aws iam put-role-policy** 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy \
       --role-name CWLtoKinesisRole \
       --policy-name Permissions-Policy-For-CWL \
       --policy-document file://~/PermissionsForCWL.json
   ```

1. 스트림이 활성 상태이고 IAM 역할을 생성하고 나면 CloudWatch Logs 대상을 생성할 수 있습니다.

   1. 이 단계를 수행해도 액세스 정책이 대상에 연결되는 것은 아니며, 대상 생성을 완료하기 위한 두 단계 중 첫 번째 단계를 완료한 것일 뿐입니다. 페이로드에 반환되는 **DestinationArn**을 적어둡니다.

      ```
      aws logs put-destination \
          --destination-name "testDestination" \
          --target-arn "arn:aws:kinesis:region:999999999999:stream/RecipientStream" \
          --role-arn "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
      
      {
        "DestinationName" : "testDestination",
        "RoleArn" : "arn:aws:iam::999999999999:role/CWLtoKinesisRole",
        "DestinationArn" : "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
        "TargetArn" : "arn:aws:kinesis:us-east-1:999999999999:stream/RecipientStream"
      }
      ```

   1. 7a 단계를 완료한 후 로그 데이터 수신자 계정에서 액세스 정책을 대상과 연결합니다. 이 정책은 **logs:PutSubscriptionFilter** 작업을 지정해야 하며, 발신자 계정에 대상에 액세스할 권한을 부여합니다.

      이 정책은 로그를 전송하는 AWS 계정에 권한을 부여합니다. 정책에서 이 계정 하나만 지정할 수 있으며, 또는 발신자 계정이 조직의 구성원인 경우 정책은 해당 조직의 조직 ID를 지정할 수 있습니다. 이렇게 하면 정책 하나만 생성하여 한 조직의 여러 계정이 이 대상 계정으로 로그를 보내도록 할 수 있습니다.

      텍스트 편집기를 사용하여 이름이 `~/AccessPolicy.json`이고 다음 정책 명령문 중 하나를 포함한 파일을 생성합니다.

      이 첫 번째 예제 정책은 ID가 `o-1234567890`인 조직의 모든 계정이 수신자 계정으로 로그를 보내도록 허용합니다.

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "",
                  "Effect": "Allow",
                  "Principal": "*",
                  "Action": "logs:PutSubscriptionFilter",
                  "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
                  "Condition": {
                      "StringEquals": {
                          "aws:PrincipalOrgID": [
                              "o-1234567890"
                          ]
                      }
                  }
              }
          ]
      }
      ```

------

      다음 예에서는 로그 데이터 발신자 계정(111111111111)에서만 로그 데이터 수신자 계정으로 로그를 보내도록 허용합니다.

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "",
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": "111111111111"
                  },
                  "Action": "logs:PutSubscriptionFilter",
                  "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination"
              }
          ]
      }
      ```

------

   1. 이전 단계에서 생성한 정책을 대상에 연결합니다.

      ```
      aws logs put-destination-policy \
          --destination-name "testDestination" \
          --access-policy file://~/AccessPolicy.json
      ```

      이 액세스 정책을 사용하면 ID가 111111111111인 AWS 계정의 사용자가 ARN arn:aws:logs:region::destination:testDestination인 대상에 대해 **PutSubscriptionFilter**를 호출할 수 있습니다.**999999999999 testDestination 다른 사용자가 이 대상에 대해 PutSubscriptionFilter를 직접 호출하려는 시도는 모두 거부됩니다.

      액세스 정책에 대한 사용자 권한의 유효성을 검사하려면 *IAM 사용 설명서*의 [정책 검사기 사용](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies_policy-validator.html)을 참조하세요.

작업을 마쳤으면 교차 계정 권한 AWS Organizations 에를 사용하는 경우의 단계를 따릅니다[2단계: (조직을 사용하는 경우에만) IAM 역할 생성](CreateSubscriptionFilter-IAMrole.md). Organizations를 사용하는 대신 다른 계정에 직접 권한을 부여하는 경우 해당 단계를 건너뛰고 [4단계: 구독 필터 생성](CreateSubscriptionFilter.md) 단계로 넘어갑니다.

# 2단계: (조직을 사용하는 경우에만) IAM 역할 생성
<a name="CreateSubscriptionFilter-IAMrole"></a>

이전 섹션에서 `111111111111` 계정이 속한 조직에 권한을 부여하는 액세스 정책을 사용하여 대상을 생성한 경우 `111111111111` 계정에 직접 권한을 부여하는 대신 이 섹션의 단계를 따릅니다. 그렇지 않다면 [4단계: 구독 필터 생성](CreateSubscriptionFilter.md) 단계로 건너뛰어도 됩니다.

이 섹션의 단계에서는 CloudWatch가 수신자 대상에 대한 구독 필터를 생성할 수 있는 권한이 발신자 계정에 있는지를 가정하고 검증할 수 있는 IAM 역할을 생성합니다.

발신자 계정에서 이 섹션의 단계를 수행합니다. 역할은 발신자 계정에 있어야 하며 구독 필터에서 이 역할의 ARN을 지정합니다. 이 예제에서 발신자 계정은 `111111111111`입니다.

**를 사용하여 교차 계정 로그 구독에 필요한 IAM 역할을 생성하려면 AWS Organizations**

1. `/TrustPolicyForCWLSubscriptionFilter.json` 파일에 다음 트러스트 정책을 생성합니다. 텍스트 편집기를 사용하여 이 정책 파일을 생성하고, IAM 콘솔은 사용하지 마세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole"
     }
   }
   ```

1. 이 정책을 사용하는 IAM 역할을 생성합니다. 명령에 의해 반환되는 `Arn` 값은 이 절차의 뒷부분에 필요하므로 메모해 둡니다. 이 예제에서 생성하는 역할의 이름으로는 `CWLtoSubscriptionFilterRole`을 사용합니다.

   ```
   aws iam create-role \ 
        --role-name CWLtoSubscriptionFilterRole \ 
        --assume-role-policy-document file://~/TrustPolicyForCWLSubscriptionFilter.json
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 다음 권한 정책을 이름이 `~/PermissionsForCWLSubscriptionFilter.json`인 파일로 생성합니다.

      ```
      { 
          "Statement": [ 
              { 
                  "Effect": "Allow", 
                  "Action": "logs:PutLogEvents", 
                  "Resource": "arn:aws:logs:region:111111111111:log-group:LogGroupOnWhichSubscriptionFilterIsCreated:*" 
              } 
          ] 
      }
      ```

   1. 다음 명령을 입력하여 방금 생성한 권한 정책을 2단계에서 생성한 역할에 연결합니다.

      ```
      aws iam put-role-policy  
          --role-name CWLtoSubscriptionFilterRole  
          --policy-name Permissions-Policy-For-CWL-Subscription-filter 
          --policy-document file://~/PermissionsForCWLSubscriptionFilter.json
      ```

작업을 마쳤으면 [4단계: 구독 필터 생성](CreateSubscriptionFilter.md) 단계로 넘어갑니다.

# 3단계: 교차 계정 대상에 대한 IAM 권한 추가/검증
<a name="Subscription-Filter-CrossAccount-Permissions"></a>

 AWS 교차 계정 정책 평가 로직에 따라 교차 계정 리소스(예: 구독 필터의 대상으로 사용되는 Kinesis 또는 Firehose 스트림)에 액세스하려면 전송 계정에 교차 계정 대상 리소스에 대한 명시적 액세스를 제공하는 자격 증명 기반 정책이 있어야 합니다. 정책 평가 로직에 대한 자세한 내용은 [교차 계정 정책 평가 로직](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic-cross-account.html)을 참조하세요.

구독 필터를 생성하는 데 사용하는 IAM 역할 또는 IAM 사용자에게 자격 증명 기반 정책을 연결할 수 있습니다. 전송 계정에 이 정책이 있어야 합니다. 관리자 역할을 사용하여 구독 필터를 만드는 경우 이 단계를 건너뛰고 [4단계: 구독 필터 생성](CreateSubscriptionFilter.md)로 넘어갈 수 있습니다.

**교차 계정에 필요한 IAM 권한을 추가 또는 검증하려면**

1. 다음 명령을 입력하여 AWS 로그 명령을 실행하는 데 사용되는 IAM 역할 또는 IAM 사용자를 확인합니다.

   ```
   aws sts get-caller-identity
   ```

   이 명령은 다음과 비슷한 출력을 반환합니다.

   ```
   {
   "UserId": "User ID",
   "Account": "sending account id",
   "Arn": "arn:aws:sending account id:role/user:RoleName/UserName"
   }
   ```

   *RoleName* 또는 *UserName*으로 나타낸 값을 기록해 둡니다.

1. 전송 계정의 AWS Management Console 에 로그인하고 1단계에서 입력한 명령의 출력에서 반환된 IAM 역할 또는 IAM 사용자가 있는 연결된 정책을 검색합니다.

1. 이 역할 또는 사용자에게 연결된 정책이 교차 계정 대상 리소스에서 `logs:PutSubscriptionFilter`을 직접 호출할 수 있는 명시적 권한을 제공하는지 확인합니다.

   다음 정책은 단일 AWS 계정인 계정 에서만 모든 대상 리소스에 구독 필터를 생성할 수 있는 권한을 제공합니다`999999999999`.

------
#### [ JSON ]

****  

   ```
   {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
           {
               "Sid": "AllowSubscriptionFiltersOnAccountResources",
               "Effect": "Allow",
               "Action": "logs:PutSubscriptionFilter",
               "Resource": [
                   "arn:aws:logs:*:*:log-group:*",
                   "arn:aws:logs:*:123456789012:destination:*"
               ]
           }
       ]
   }
   ```

------

   다음 정책은 단일 AWS 계정인 계정에서 라는 특정 대상 리소스에 대해서만 구독 필터를 생성할 `sampleDestination` 수 있는 권한을 제공합니다`123456789012`.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "AllowSubscriptionFiltersonAccountResource",
               "Effect": "Allow",
               "Action": "logs:PutSubscriptionFilter",
               "Resource": [
                   "arn:aws:logs:*:*:log-group:*",
                   "arn:aws:logs:*:123456789012:destination:sampleDestination"
               ]
           }
       ]
   }
   ```

------

# 4단계: 구독 필터 생성
<a name="CreateSubscriptionFilter"></a>

대상을 생성하고 나면 로그 데이터 수신자 계정에서 다른 AWS 계정이 로그 이벤트를 동일한 대상으로 전송할 수 있도록 대상 ARN(arn:aws:logs:us-east-1:999999999999:destination:testDestination)을 이들과 공유할 수 있습니다. 그러면 이러한 다른 전송 계정 사용자는 이 대상에 해당되는 로그 그룹에 대한 구독 필터를 생성합니다. 그 즉시 구독 필터는 실시간으로 선택한 로그 그룹에서 지정된 스트림으로 로그 데이터를 이동시키기 시작합니다.

**참고**  
전체 조직에 구독 필터에 대한 권한을 부여하는 경우 [2단계: (조직을 사용하는 경우에만) IAM 역할 생성](CreateSubscriptionFilter-IAMrole.md)에서 생성한 IAM 역할의 ARN을 사용해야 합니다.

다음 예제에서는 전송 계정에 구독 필터가 생성됩니다.이 필터는 이벤트가 포함된 AWS CloudTrail 로그 그룹과 연결되어 "루트" AWS 자격 증명에 의해 기록된 모든 활동이 이전에 생성한 대상으로 전달됩니다. 이 대상에서는 'RecipientStream'이라는 스트림을 캡슐화합니다.

다음 섹션의 나머지 단계에서는 *AWS CloudTrail 사용 설명서*의 [CloudWatch Logs로 CloudTrail 이벤트 전송](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html) 지침을 따른 후 CloudTrail 이벤트를 포함하는 로그 그룹을 만들었다고 가정합니다. 이 단계에서는 이 로그 그룹의 이름이 `CloudTrail/logs`라고 가정합니다.

다음 명령을 입력할 때는[3단계: 교차 계정 대상에 대한 IAM 권한 추가/검증](Subscription-Filter-CrossAccount-Permissions.md)에서 IAM 사용자로 로그인하거나 정책을 추가한 IAM 역할을 사용하여 로그인해야 합니다.

```
aws logs put-subscription-filter \
    --log-group-name "CloudTrail/logs" \
    --filter-name "RecipientStream" \
    --filter-pattern "{$.userIdentity.type = Root}" \
    --destination-arn "arn:aws:logs:region:999999999999:destination:testDestination"
```

로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상은 다른 리전에 있는 Amazon Kinesis Data Streams 스트림과 같은 AWS 리소스를 가리킬 수 있습니다.

# 로그 이벤트 흐름 검증
<a name="ValidateLogEventFlow"></a>

구독 필터를 생성하고 나면 CloudWatch Logs가 들어오는 모든 로그 이벤트 중에서 필터 패턴과 일치하는 이벤트를 "**RecipientStream**"이라는 대상 스트림 내에서 캡슐화된 스트림으로 전달합니다. 대상 소유자는 **aws kinesis get-shard-iterator** 명령을 사용하여 Amazon Kinesis Data Streams 샤드를 캡처하고 **aws kinesis get-records** 명령을 사용하여 일부 Amazon Kinesis Data Streams 레코드를 가져와서이 문제가 발생하고 있는지 확인할 수 있습니다.

```
aws kinesis get-shard-iterator \
      --stream-name RecipientStream \
      --shard-id shardId-000000000000 \
      --shard-iterator-type TRIM_HORIZON

{
    "ShardIterator":
    "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiKEXAMPLE"
}

aws kinesis get-records \
      --limit 10 \
      --shard-iterator
      "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiKEXAMPLE"
```

**참고**  
Amazon Kinesis Data Streams가 데이터를 반환하기 전에 get-records 명령을 몇 번 다시 실행해야 할 수 있습니다.

Amazon Kinesis Data Streams 레코드 배열이 포함된 응답이 표시됩니다. Amazon Kinesis Data Streams 레코드의 데이터 속성은 gzip 형식으로 압축된 다음 base64로 인코딩됩니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

```
echo -n "<Content of Data>" | base64 -d | zcat
```

디코딩 및 압축 해제된 base64 데이터는 다음 구조를 가진 JSON으로 포맷됩니다.

```
{
    "owner": "111111111111",
    "logGroup": "CloudTrail/logs",
    "logStream": "111111111111_CloudTrail/logs_us-east-1",
    "subscriptionFilters": [
        "RecipientStream"
    ],
    "messageType": "DATA_MESSAGE",
    "logEvents": [
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        },
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        },
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        }
    ]
}
```

이 데이터 구조에서의 키 요소는 다음과 같습니다.

**owner**  
원본 로그 데이터의 AWS 계정 ID입니다.

**logGroup**  
원본 로그 데이터의 로그 그룹 이름.

**logStream**  
원본 로그 데이터의 로그 스트림 이름.

**subscriptionFilters**  
원본 로그 데이터과 일치한 구독 필터 이름 목록입니다.

**messageType**  
데이터 메시지는 'DATA\$1MESSAGE' 유형을 사용합니다. CloudWatch Logs는 주로 대상에 연결할 수 있는지 확인하기 위해 "CONTROL\$1MESSAGE" 유형의 Amazon Kinesis Data Streams 레코드를 내보낼 수 있습니다.

**logEvents**  
로그 이벤트 레코드의 배열로 표현되는 실제 로그 데이터. ID 속성은 모든 로그 이벤트의 고유 식별자입니다.

# 런타임 시 대상 멤버십 수정
<a name="ModifyDestinationMembership"></a>

소유된 대상에서 몇몇 사용자의 멤버십을 추가 또는 제거해야 하는 상황에 직면할 수 있습니다. 새 액세스 정책과 함께 대상에 `put-destination-policy` 명령을 사용할 수 있습니다. 다음 예제에서는 이전에 추가한 계정인 **111111111111**이 추가적인 로그 데이터 전송을 중단하고 계정 **222222222222**가 활성화됩니다.

1. 대상 **testDestination**에 현재 연결된 정책을 가져와서 **AccessPolicy**를 적어둡니다.

   ```
   aws logs describe-destinations \
       --destination-name-prefix "testDestination"
   
   {
    "Destinations": [
      {
        "DestinationName": "testDestination",
        "RoleArn": "arn:aws:iam::999999999999:role/CWLtoKinesisRole",
        "DestinationArn": "arn:aws:logs:region:999999999999:destination:testDestination",
        "TargetArn": "arn:aws:kinesis:region:999999999999:stream/RecipientStream",
        "AccessPolicy": "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Sid\": \"\", \"Effect\": \"Allow\", \"Principal\": {\"AWS\": \"111111111111\"}, \"Action\": \"logs:PutSubscriptionFilter\", \"Resource\": \"arn:aws:logs:region:999999999999:destination:testDestination\"}] }"
      }
    ]
   }
   ```

1. 계정 **111111111111**이 중단되고 계정 **222222222222**가 활성화되었음을 반영하도록 이 정책을 업데이트합니다. **\$1/NewAccessPolicy.json** 파일에 이 정책을 저장합니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "222222222222"
               },
               "Action": "logs:PutSubscriptionFilter",
               "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination"
           }
       ]
   }
   ```

------

1. **PutDestinationPolicy**를 직접 호출하여 **NewAccessPolicy.json** 파일에 정의된 정책을 대상에 연결합니다.

   ```
   aws logs put-destination-policy \
   --destination-name "testDestination" \
   --access-policy file://~/NewAccessPolicy.json
   ```

   이렇게 하면 계정 ID **111111111111**에서 로그 이벤트가 비활성화됩니다. 계정 ID **222222222222**에서 나온 로그 이벤트는 계정 **222222222222** 의 소유자가 구독 필터를 생성하고 나면 그 즉시 대상으로 이동하기 시작합니다.

# 기존 교차 계정 구독 업데이트
<a name="Cross-Account-Log_Subscription-Update"></a>

현재 대상 계정이 특정 발신자 계정에만 권한을 부여하는 교차 계정 로그 구독이 있고 대상 계정이 조직의 모든 계정에 대한 액세스 권한을 부여하도록 이 구독을 업데이트하려는 경우 이 섹션의 단계를 따릅니다.

**Topics**
+ [1단계: 구독 필터 업데이트](Cross-Account-Log_Subscription-Update-filter.md)
+ [2단계: 기존 대상 액세스 정책 업데이트](Cross-Account-Log_Subscription-Update-policy.md)

# 1단계: 구독 필터 업데이트
<a name="Cross-Account-Log_Subscription-Update-filter"></a>

**참고**  
이 단계는 [AWS 서비스에서 로깅 활성화](AWS-logs-and-resource-policy.md)에 나열된 서비스에서 생성된 로그에 대한 교차 계정 구독에만 필요합니다. 해당 로그 그룹 중 하나에서 생성된 로그로 작업하지 않는 경우 [2단계: 기존 대상 액세스 정책 업데이트](Cross-Account-Log_Subscription-Update-policy.md) 섹션으로 건너뛸 수 있습니다.

경우에 따라 대상 계정으로 로그를 보내는 모든 발신자 계정의 구독 필터를 업데이트해야 합니다. 업데이트에는 IAM 역할이 추가됩니다. IAM 역할은 CloudWatch에서 발신자 계정이 수신자 계정에 로그를 보낼 수 있는 권한이 있는지를 가정하고 검증할 수 있습니다.

교차 계정 구독 권한에 대해 조직 ID를 사용하도록 업데이트하려는 모든 발신자 계정에 대해서는 이 섹션의 단계를 따릅니다.

이 섹션의 예제에서 두 개의 `111111111111` 계정 및 `222222222222` 계정은 `999999999999` 계정에 로그를 전송하기 위해 생성된 구독 필터를 이미 가지고 있습니다. 기존 구독 필터 값은 다음과 같습니다.

```
## Existing Subscription Filter parameter values
    \ --log-group-name "my-log-group-name" 
    \ --filter-name "RecipientStream" 
    \ --filter-pattern "{$.userIdentity.type = Root}" 
    \ --destination-arn "arn:aws:logs:region:999999999999:destination:testDestination"
```

현재 구독 필터 파라미터 값을 찾아야 하는 경우 다음 명령을 입력합니다.

```
aws logs describe-subscription-filters 
    \ --log-group-name "my-log-group-name"
```

**교차 계정 로그 권한에 대한 조직 ID 사용을 시작하도록 구독 필터 업데이트**

1. `~/TrustPolicyForCWL.json` 파일에 다음 트러스트 정책을 생성합니다. 텍스트 편집기를 사용하여 이 정책 파일을 생성하고, IAM 콘솔은 사용하지 마세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole"
     }
   }
   ```

1. 이 정책을 사용하는 IAM 역할을 생성합니다. 명령에 의해 반환되는 `Arn` 값의 `Arn` 값은 이 절차의 뒷부분에 필요하므로 메모해 둡니다. 이 예제에서 생성하는 역할의 이름으로는 `CWLtoSubscriptionFilterRole`을 사용합니다.

   ```
   aws iam create-role 
       \ --role-name CWLtoSubscriptionFilterRole 
       \ --assume-role-policy-document file://~/TrustPolicyForCWL.json
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 다음 권한 정책을 이름이 `/PermissionsForCWLSubscriptionFilter.json`인 파일로 생성합니다.

      ```
      { 
          "Statement": [ 
              { 
                  "Effect": "Allow", 
                  "Action": "logs:PutLogEvents", 
                  "Resource": "arn:aws:logs:region:111111111111:log-group:LogGroupOnWhichSubscriptionFilterIsCreated:*" 
              } 
          ] 
      }
      ```

   1. 다음 명령을 입력하여 방금 생성한 권한 정책을 2단계에서 생성한 역할에 연결합니다.

      ```
      aws iam put-role-policy 
          --role-name CWLtoSubscriptionFilterRole 
          --policy-name Permissions-Policy-For-CWL-Subscription-filter 
          --policy-document file://~/PermissionsForCWLSubscriptionFilter.json
      ```

1. 다음 명령을 입력하여 구독 필터를 업데이트합니다.

   ```
   aws logs put-subscription-filter 
       \ --log-group-name "my-log-group-name" 
       \ --filter-name "RecipientStream" 
       \ --filter-pattern "{$.userIdentity.type = Root}" 
       \ --destination-arn "arn:aws:logs:region:999999999999:destination:testDestination"
       \ --role-arn "arn:aws:iam::111111111111:role/CWLtoSubscriptionFilterRole"
   ```

# 2단계: 기존 대상 액세스 정책 업데이트
<a name="Cross-Account-Log_Subscription-Update-policy"></a>

모든 발신자 계정에서 구독 필터를 업데이트한 후, 수신자 계정에서 대상 액세스 정책을 업데이트할 수 있습니다.

다음 예제에서 수신자 계정은 `999999999999`이며 대상의 이름은 `testDestination`입니다.

업데이트를 통해 ID가 `o-1234567890`인 조직의 모든 계정이 수신자 계정으로 로그를 보낼 수 있습니다. 구독 필터가 생성된 계정만이 실제로 수신자 계정에 로그를 보냅니다.

**수신자 계정의 대상 액세스 정책을 업데이트하여 권한에 대한 조직 ID 사용**

1. 수신자 계정에서 텍스트 편집기를 사용하여 다음 내용을 포함한 `~/AccessPolicy.json` 파일을 생성합니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": "*",
               "Action": "logs:PutSubscriptionFilter",
               "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
               "Condition": {
                   "StringEquals": {
                       "aws:PrincipalOrgID": [
                           "o-1234567890"
                       ]
                   }
               }
           }
       ]
   }
   ```

------

1. 다음 명령을 입력하여 방금 생성한 정책을 기존 대상에 연결합니다. 특정 AWS 계정 ID를 나열하는 액세스 정책 대신 조직 IDs로 액세스 정책을 사용하도록 대상을 업데이트하려면 `force` 파라미터를 포함합니다.
**주의**  
에 나열된 AWS 서비스에서 전송한 로그로 작업[AWS 서비스에서 로깅 활성화](AWS-logs-and-resource-policy.md)하는 경우이 단계를 수행하기 전에 먼저에 설명된 대로 모든 발신자 계정의 구독 필터를 업데이트해야 합니다[1단계: 구독 필터 업데이트](Cross-Account-Log_Subscription-Update-filter.md).

   ```
   aws logs put-destination-policy 
       \ --destination-name "testDestination" 
       \ --access-policy file://~/AccessPolicy.json
       \ --force
   ```

# Firehose를 사용한 교차 계정 교차 리전 로그 데이터 공유
<a name="CrossAccountSubscriptions-Firehose"></a>

계정에서 로그 데이터를 공유하려면 로그 데이터 발신자 및 수신자를 설정해야 합니다.
+ **로그 데이터 발신자** - 수신자로부터 대상 정보를 얻고 지정된 대상으로 로그 이벤트를 전송할 준비가 되었음을 CloudWatch Logs에 알립니다. 이 섹션의 나머지 부분에서는 가상 AWS 계정 번호가 111111111111인 로그 데이터 발신자가 표시됩니다.
+ **로그 데이터 수신자** - Amazon Kinesis Data Streams 스트림을 캡슐화하는 대상을 설정하고 CloudWatch Logs에 수신자가 로그 데이터를 수신하고 싶다는 사실을 알립니다. 그런 다음 수신자는 이 대상에 대한 정보를 발신자와 공유합니다. 이 섹션의 나머지 부분에서는 로그 데이터 수신자가 가상 AWS 계정 번호 222222222222로 표시됩니다.

이 섹션의 예에서는 Amazon S3 스토리지와 함께 Firehose 전송 스트림을 사용합니다. 다른 설정을 사용하여 Firehose 전송 스트림을 설정할 수도 있습니다. 자세한 내용은 [Creating a Firehose Delivery Stream](https://docs.aws.amazon.com/firehose/latest/dev/basic-create.html)을 참조하세요.

**참고**  
로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상이 가리키는 AWS 리소스는 다른 리전에 위치할 수 있습니다.

**참고**  
 ***동일한 계정*** 및 ***교차 리전*** 전송 스트림에 대한 Firehose 구독 필터가 지원됩니다.

**Topics**
+ [1단계: Firehose 전송 스트림 생성](CreateFirehoseStream.md)
+ [2단계: 대상 생성](CreateFirehoseStreamDestination.md)
+ [3단계: 교차 계정 대상에 대한 IAM 권한 추가/검증](Subscription-Filter-CrossAccount-Permissions-Firehose.md)
+ [4단계: 구독 필터 생성](CreateSubscriptionFilterFirehose.md)
+ [로그 이벤트 흐름 검증](ValidateLogEventFlowFirehose.md)
+ [런타임 시 대상 멤버십 수정](ModifyDestinationMembershipFirehose.md)

# 1단계: Firehose 전송 스트림 생성
<a name="CreateFirehoseStream"></a>

**중요**  
 다음 단계를 완료하기 전에 Firehose가 Amazon S3 버킷에 액세스할 수 있도록 액세스 정책을 사용해야 합니다. 자세한 내용은 *Amazon Data Firehose 개발자 가이드*의 [액세스 제어](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html#using-iam-s3)를 참조하세요.  
 이 섹션(1단계)의 모든 단계는 로그 데이터 수신자 계정에서 수행해야 합니다.  
 미국 동부(버지니아 북부)가 다음 샘플 명령에 사용됩니다. 이 리전을 배포에 적합한 리전으로 바꿉니다.

**대상으로 사용할 Firehose 전송 스트림을 생성하려면**

1. Amazon S3 버킷 생성:

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-bucket --create-bucket-configuration LocationConstraint=us-east-1
   ```

1. 버킷에 데이터를 입력하는 데 필요한 권한을 Firehose에 부여하는 IAM 역할을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 `~/TrustPolicyForFirehose.json` 파일에 신뢰 정책을 생성합니다.

      ```
      { "Statement": { "Effect": "Allow", "Principal": { "Service": "firehose.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId":"222222222222" } } } }
      ```

   1. IAM 역할을 생성하여 방금 생성한 신뢰 정책 파일을 지정합니다.

      ```
      aws iam create-role \ 
          --role-name FirehosetoS3Role \ 
          --assume-role-policy-document file://~/TrustPolicyForFirehose.json
      ```

   1. 이 명령의 출력은 다음과 비슷합니다. 역할 이름과 역할 ARN을 기록해둡니다.

      ```
      {
          "Role": {
              "Path": "/",
              "RoleName": "FirehosetoS3Role",
              "RoleId": "AROAR3BXASEKW7K635M53",
              "Arn": "arn:aws:iam::222222222222:role/FirehosetoS3Role",
              "CreateDate": "2021-02-02T07:53:10+00:00",
              "AssumeRolePolicyDocument": {
                  "Statement": {
                      "Effect": "Allow",
                      "Principal": {
                          "Service": "firehose.amazonaws.com"
                      },
                      "Action": "sts:AssumeRole",
                      "Condition": {
                          "StringEquals": {
                              "sts:ExternalId": "222222222222"
                          }
                      }
                  }
              }
          }
      }
      ```

1. Firehose가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 다음 권한 정책을 이름이 `~/PermissionsForFirehose.json`인 파일로 생성합니다. 사용 사례에 따라 이 파일에 권한을 더 추가해야 할 수도 있습니다.

      ```
      {
          "Statement": [{
              "Effect": "Allow",
              "Action": [
                  "s3:PutObject",
                  "s3:PutObjectAcl",
                  "s3:ListBucket"
              ],
              "Resource": [
                  "arn:aws:s3:::amzn-s3-demo-bucket",
                  "arn:aws:s3:::amzn-s3-demo-bucket/*"
              ]
          }]
      }
      ```

   1. 다음 명령을 입력하여 방금 생성한 권한 정책을 IAM 역할에 연결합니다.

      ```
      aws iam put-role-policy --role-name FirehosetoS3Role --policy-name Permissions-Policy-For-Firehose-To-S3 --policy-document file://~/PermissionsForFirehose.json
      ```

1. 다음 명령을 입력하여 Firehose 전송 스트림을 생성합니다. *my-role-arn* 및 *amzn-s3-demo-bucket2-arn*을 배포에 올바른 값으로 바꿉니다.

   ```
   aws firehose create-delivery-stream \
      --delivery-stream-name 'my-delivery-stream' \
      --s3-destination-configuration \
     '{"RoleARN": "arn:aws:iam::222222222222:role/FirehosetoS3Role", "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket"}'
   ```

   출력은 다음과 비슷하게 보여야 합니다.

   ```
   {
       "DeliveryStreamARN": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream"
   }
   ```

# 2단계: 대상 생성
<a name="CreateFirehoseStreamDestination"></a>

**중요**  
이 절차의 모든 단계는 로그 데이터 수신자 계정에서 수행되어야 합니다.

대상이 생성되면 CloudWatch Logs는 수신자 계정을 대신하여 대상에게 테스트 메시지를 보냅니다. 구독 필터가 나중에 활성화되면 CloudWatch Logs는 소스 계정을 대신하여 대상에게 로그 이벤트를 보냅니다.

**대상을 생성하려면**

1. [1단계: Firehose 전송 스트림 생성](CreateFirehoseStream.md)에서 생성한 Firehose 스트림이 활성화될 때까지 기다립니다. 다음 명령을 사용하여 **StreamDescription.StreamStatus** 속성을 확인할 수 있습니다.

   ```
   aws firehose describe-delivery-stream --delivery-stream-name "my-delivery-stream"
   ```

   또한 이후 단계에서 사용해야 하기 때문에 **DeliveryStreamDescription.DeliveryStreamARN** 값을 기록해 둡니다. 이 명령의 샘플 출력:

   ```
   {
       "DeliveryStreamDescription": {
           "DeliveryStreamName": "my-delivery-stream",
           "DeliveryStreamARN": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream",
           "DeliveryStreamStatus": "ACTIVE",
           "DeliveryStreamEncryptionConfiguration": {
               "Status": "DISABLED"
           },
           "DeliveryStreamType": "DirectPut",
           "VersionId": "1",
           "CreateTimestamp": "2021-02-01T23:59:15.567000-08:00",
           "Destinations": [
               {
                   "DestinationId": "destinationId-000000000001",
                   "S3DestinationDescription": {
                       "RoleARN": "arn:aws:iam::222222222222:role/FirehosetoS3Role",
                       "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket",
                       "BufferingHints": {
                           "SizeInMBs": 5,
                           "IntervalInSeconds": 300
                       },
                       "CompressionFormat": "UNCOMPRESSED",
                       "EncryptionConfiguration": {
                           "NoEncryptionConfig": "NoEncryption"
                       },
                       "CloudWatchLoggingOptions": {
                           "Enabled": false
                       }
                   },
                   "ExtendedS3DestinationDescription": {
                       "RoleARN": "arn:aws:iam::222222222222:role/FirehosetoS3Role",
                       "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket",
                       "BufferingHints": {
                           "SizeInMBs": 5,
                           "IntervalInSeconds": 300
                       },
                       "CompressionFormat": "UNCOMPRESSED",
                       "EncryptionConfiguration": {
                           "NoEncryptionConfig": "NoEncryption"
                       },
                       "CloudWatchLoggingOptions": {
                           "Enabled": false
                       },
                       "S3BackupMode": "Disabled"
                   }
               }
           ],
           "HasMoreDestinations": false
       }
   }
   ```

   전송 스트림이 활성 상태가 될 때까지 1\$12분 정도 기다려야 할 수 있습니다.

1. 전송 스트림이 활성 상태가 되면 Firehose 스트림으로 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 **\$1/TrustPolicyForCWL.json** 파일에서 신뢰 정책을 생성해야 합니다. 텍스트 편집기를 사용하여 이 정책을 생성합니다. CloudWatch Logs 엔드포인트에 대한 자세한 내용은 [Amazon CloudWatch Logs 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/cwl_region.html)을 참조하세요.

   이 정책은 `sourceAccountId`를 지정하여 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키를 포함합니다. 첫 번째 직접 호출에서 소스 계정 ID를 아직 모르는 경우 소스 ARN 필드에 대상 ARN을 넣는 것이 좋습니다. 후속 직접 호출에서는 소스 ARN을 첫 번째 직접 호출에서 수집한 실제 소스 ARN으로 설정해야 합니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 단원을 참조하십시오.

   ```
   {
       "Statement": {
           "Effect": "Allow",
           "Principal": {
               "Service": "logs.region.amazonaws.com"
           },
           "Action": "sts:AssumeRole",
           "Condition": {
               "StringLike": {
                   "aws:SourceArn": [
                       "arn:aws:logs:region:sourceAccountId:*",
                       "arn:aws:logs:region:recipientAccountId:*"
                   ]
               }
           }
        }
   }
   ```

1. **aws iam create-role** 명령을 사용하여 IAM 역할을 생성해 방금 만든 신뢰 정책 파일을 지정합니다.

   ```
   aws iam create-role \
         --role-name CWLtoKinesisFirehoseRole \
         --assume-role-policy-document file://~/TrustPolicyForCWL.json
   ```

   다음은 샘플 출력입니다. 이후 단계에서 사용해야 하므로 반환된 `Role.Arn` 값을 메모해 둡니다.

   ```
   {
       "Role": {
           "Path": "/",
           "RoleName": "CWLtoKinesisFirehoseRole",
           "RoleId": "AROAR3BXASEKYJYWF243H",
           "Arn": "arn:aws:iam::222222222222:role/CWLtoKinesisFirehoseRole",
           "CreateDate": "2021-02-02T08:10:43+00:00",
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "logs.region.amazonaws.com"
                   },
                   "Action": "sts:AssumeRole",
                   "Condition": {
                       "StringLike": {
                           "aws:SourceArn": [
                               "arn:aws:logs:region:sourceAccountId:*",
                               "arn:aws:logs:region:recipientAccountId:*"
                           ]
                       }
                   }
               }
           }
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 권한 정책을 **\$1/PermissionsForCWL.json** 파일로 생성합니다.

   ```
   {
       "Statement":[
         {
           "Effect":"Allow",
           "Action":["firehose:*"],
           "Resource":["arn:aws:firehose:region:222222222222:*"]
         }
       ]
   }
   ```

1. 다음 명령을 입력하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy --role-name CWLtoKinesisFirehoseRole --policy-name Permissions-Policy-For-CWL --policy-document file://~/PermissionsForCWL.json
   ```

1. Firehose 전송 스트림이 활성 상태이고 IAM 역할을 생성하고 나면 CloudWatch Logs 대상을 생성할 수 있습니다.

   1. 이 단계를 수행했다고 액세스 정책이 대상에 연결되는 것은 아니며, 대상 생성을 완료하기 위한 두 단계 중 첫 번째 단계일 뿐입니다. 페이로드에서 반환된 새 대상의 ARN은 이후 단계에서 `destination.arn`으로 사용할 것이므로 메모해 둡니다.

      ```
      aws logs put-destination \                                                       
          --destination-name "testFirehoseDestination" \
          --target-arn "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream" \
          --role-arn "arn:aws:iam::222222222222:role/CWLtoKinesisFirehoseRole"
      
      {
          "destination": {
              "destinationName": "testFirehoseDestination",
              "targetArn": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream",
              "roleArn": "arn:aws:iam::222222222222:role/CWLtoKinesisFirehoseRole",
              "arn": "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"}
      }
      ```

   1. 이전 단계를 완료한 후 로그 데이터 수신자 계정(222222222222)에서 액세스 정책을 대상과 연결합니다.

      이 정책을 사용하면 로그 데이터 발신자 계정(111111111111)이 로그 데이터 수신자 계정(222222222222)만의 대상에 액세스할 수 있습니다. 텍스트 편집기를 사용하여 이 정책을 **\$1/AccessPolicy.json** 파일에 저장할 수 있습니다.

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement" : [
          {
            "Sid" : "",
            "Effect" : "Allow",
            "Principal" : {
              "AWS" : "111111111111"
            },
            "Action" : "logs:PutSubscriptionFilter",
            "Resource" : "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"
          }
        ]
      }
      ```

------

   1. 이렇게 하면 대상에 대해 쓰기 액세스 권한을 가진 사람을 정의하는 정책이 생성됩니다. 이 정책은 대상 액세스를 위한 **logs:PutSubscriptionFilter** 작업을 지정하게 됩니다. 교차 계정 사용자는 **PutSubscriptionFilter** 작업을 사용해 대상에 로그 이벤트를 전송합니다.

      ```
      aws logs put-destination-policy \
          --destination-name "testFirehoseDestination" \
          --access-policy file://~/AccessPolicy.json
      ```

# 3단계: 교차 계정 대상에 대한 IAM 권한 추가/검증
<a name="Subscription-Filter-CrossAccount-Permissions-Firehose"></a>

 AWS 교차 계정 정책 평가 로직에 따라 교차 계정 리소스(예: 구독 필터의 대상으로 사용되는 Kinesis 또는 Firehose 스트림)에 액세스하려면 전송 계정에 교차 계정 대상 리소스에 대한 명시적 액세스를 제공하는 자격 증명 기반 정책이 있어야 합니다. 정책 평가 로직에 대한 자세한 내용은 [교차 계정 정책 평가 로직](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic-cross-account.html)을 참조하세요.

구독 필터를 생성하는 데 사용하는 IAM 역할 또는 IAM 사용자에게 자격 증명 기반 정책을 연결할 수 있습니다. 전송 계정에 이 정책이 있어야 합니다. 관리자 역할을 사용하여 구독 필터를 만드는 경우 이 단계를 건너뛰고 [4단계: 구독 필터 생성](CreateSubscriptionFilter.md)로 넘어갈 수 있습니다.

**교차 계정에 필요한 IAM 권한을 추가 또는 검증하려면**

1. 다음 명령을 입력하여 AWS 로그 명령을 실행하는 데 사용되는 IAM 역할 또는 IAM 사용자를 확인합니다.

   ```
   aws sts get-caller-identity
   ```

   이 명령은 다음과 비슷한 출력을 반환합니다.

   ```
   {
   "UserId": "User ID",
   "Account": "sending account id",
   "Arn": "arn:aws:sending account id:role/user:RoleName/UserName"
   }
   ```

   *RoleName* 또는 *UserName*으로 나타낸 값을 기록해 둡니다.

1. 전송 계정의 AWS Management Console 에 로그인하고 1단계에서 입력한 명령의 출력에서 반환된 IAM 역할 또는 IAM 사용자가 있는 연결된 정책을 검색합니다.

1. 이 역할 또는 사용자에게 연결된 정책이 교차 계정 대상 리소스에서 `logs:PutSubscriptionFilter`을 직접 호출할 수 있는 명시적 권한을 제공하는지 확인합니다.

   다음 정책은 단일 AWS 계정인 계정 에서만 모든 대상 리소스에 구독 필터를 생성할 수 있는 권한을 제공합니다`999999999999`.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "AllowSubscriptionFiltersOnAnyResourceInOneSpecificAccount",
               "Effect": "Allow",
               "Action": "logs:PutSubscriptionFilter",
               "Resource": [
                   "arn:aws:logs:*:*:log-group:*",
                   "arn:aws:logs:*:123456789012:destination:*"
               ]
           }
       ]
   }
   ```

------

   다음 정책은 단일 AWS 계정인 계정에서 라는 특정 대상 리소스에 대해서만 구독 필터를 생성할 `sampleDestination` 수 있는 권한을 제공합니다`123456789012`.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
           "Sid": "AllowSubscriptionFiltersOnSpecificResource",
               "Effect": "Allow",
               "Action": "logs:PutSubscriptionFilter",
               "Resource": [
                   "arn:aws:logs:*:*:log-group:*",
                   "arn:aws:logs:*:123456789012:destination:amzn-s3-demo-bucket"
               ]
           }
       ]
   }
   ```

------

# 4단계: 구독 필터 생성
<a name="CreateSubscriptionFilterFirehose"></a>

이 예제에서는 111111111111인 전송 계정으로 전환합니다. 이제 전송 계정에서 구독 필터를 생성합니다. 이 예제에서 필터는 AWS CloudTrail 이벤트가 포함된 로그 그룹과 연결되어 "루트" AWS 자격 증명에 의해 기록된 모든 활동이 이전에 생성한 대상으로 전달됩니다. CloudWatch Logs로 AWS CloudTrail 이벤트를 전송하는 방법에 대한 자세한 내용은 *AWS CloudTrail 사용 설명서*의 [CloudWatch Logs로 CloudTrail CloudTrail 이벤트 전송](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html)을 참조하세요.

다음 명령을 입력할 때는[3단계: 교차 계정 대상에 대한 IAM 권한 추가/검증](Subscription-Filter-CrossAccount-Permissions-Firehose.md)에서 IAM 사용자로 로그인하거나 정책을 추가한 IAM 역할을 사용하여 로그인해야 합니다.

```
aws logs put-subscription-filter \
    --log-group-name "aws-cloudtrail-logs-111111111111-300a971e" \                   
    --filter-name "firehose_test" \
    --filter-pattern "{$.userIdentity.type = AssumedRole}" \
    --destination-arn "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"
```

로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상은 다른 리전에 있는 Firehose 스트림과 같은 AWS 리소스를 가리킬 수 있습니다.

# 로그 이벤트 흐름 검증
<a name="ValidateLogEventFlowFirehose"></a>

구독 필터를 생성하고 나면 CloudWatch Logs는 모든 수신 로그 이벤트 중에서 필터 패턴과 일치하는 이벤트를 Firehose 전송 스트림으로 전달합니다. Firehose 전송 스트림에 설정된 시간 버퍼 간격에 따라 Amazon S3 버킷에 데이터가 나타나기 시작합니다. 충분한 시간이 지나고 나면 Amazon S3 버킷을 확인하여 데이터를 확인할 수 있습니다. 버킷을 확인하려면 다음 명령을 입력합니다.

```
aws s3api list-objects --bucket 'amzn-s3-demo-bucket' 
```

해당 명령은 다음과 비슷하게 출력됩니다.

```
{
    "Contents": [
        {
            "Key": "2021/02/02/08/my-delivery-stream-1-2021-02-02-08-55-24-5e6dc317-071b-45ba-a9d3-4805ba39c2ba",
            "LastModified": "2021-02-02T09:00:26+00:00",
            "ETag": "\"EXAMPLEa817fb88fc770b81c8f990d\"",
            "Size": 198,
            "StorageClass": "STANDARD",
            "Owner": {
                "DisplayName": "firehose+2test",
                "ID": "EXAMPLE27fd05889c665d2636218451970ef79400e3d2aecca3adb1930042e0"
            }
        }
    ]
}
```

다음 명령을 입력하여 버킷에서 특정 객체를 검색할 수 있습니다. 이전 명령에서 찾은 값으로 `key`의 값을 바꿉니다.

```
aws s3api get-object --bucket 'amzn-s3-demo-bucket' --key '2021/02/02/08/my-delivery-stream-1-2021-02-02-08-55-24-5e6dc317-071b-45ba-a9d3-4805ba39c2ba' testfile.gz
```

Amazon S3 객체의 데이터는 gzip 형식으로 압축됩니다. 다음 명령 중 하나를 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

Linux:

```
zcat testfile.gz
```

macOS:

```
zcat <testfile.gz
```

# 런타임 시 대상 멤버십 수정
<a name="ModifyDestinationMembershipFirehose"></a>

소유한 대상에서 로그 발신자를 추가 또는 제거해야 하는 상황에 직면할 수 있습니다. 새 액세스 정책에서는 대상에 대해 **PutDestinationPolicy** 작업을 사용할 수 있습니다. 다음 예제에서는 이전에 추가한 계정인 **111111111111**이 추가적인 로그 데이터 전송을 중단하고 계정 **333333333333**이 활성화됩니다.

1. 대상 **testDestination**에 현재 연결된 정책을 가져와서 **AccessPolicy**를 적어둡니다.

   ```
   aws logs describe-destinations \
       --destination-name-prefix "testFirehoseDestination"
   
   {
       "destinations": [
           {
               "destinationName": "testFirehoseDestination",
               "targetArn": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream",
               "roleArn": "arn:aws:iam:: 222222222222:role/CWLtoKinesisFirehoseRole",
               "accessPolicy": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [\n    {\n      \"Sid\" : \"\",\n      \"Effect\" : \"Allow\",\n      \"Principal\" : {\n        \"AWS\" : \"111111111111 \"\n      },\n      \"Action\" : \"logs:PutSubscriptionFilter\",\n      \"Resource\" : \"arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination\"\n    }\n  ]\n}\n\n",
               "arn": "arn:aws:logs:us-east-1: 222222222222:destination:testFirehoseDestination",
               "creationTime": 1612256124430
           }
       ]
   }
   ```

1. 계정 **111111111111**이 중단되고 계정 **333333333333**이 활성화되었음을 반영하도록 이 정책을 업데이트합니다. **\$1/NewAccessPolicy.json** 파일에 이 정책을 저장합니다.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement" : [
       {
         "Sid" : "",
         "Effect" : "Allow",
         "Principal" : {
           "AWS" : "333333333333 "
         },
         "Action" : "logs:PutSubscriptionFilter",
         "Resource" : "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"
       }
     ]
   }
   ```

------

1. 다음 명령을 사용하여 **NewAccessPolicy.json** 파일에 정의된 정책을 대상과 연결합니다.

   ```
   aws logs put-destination-policy \
       --destination-name "testFirehoseDestination" \                                                                              
       --access-policy file://~/NewAccessPolicy.json
   ```

   이렇게 하면 계정 ID **111111111111**에서 로그 이벤트가 비활성화됩니다. 계정 ID **333333333333**에서 나온 로그 이벤트는 계정 **333333333333**의 소유자가 구독 필터를 생성하고 나면 그 즉시 대상으로 이동하기 시작합니다.

# Amazon Kinesis Data Streams를 사용한 교차 계정 교차 리전 계정 수준 구독
<a name="CrossAccountSubscriptions-Kinesis-Account"></a>

교차 계정 구독을 생성할 때 단일 계정 또는 조직을 발신자로 지정할 수 있습니다. 조직을 지정하는 경우 이 절차를 통해 조직의 모든 계정에서 수신자 계정으로 로그를 보낼 수 있습니다.

계정에서 로그 데이터를 공유하려면 로그 데이터 발신자 및 수신자를 설정해야 합니다.
+ **로그 데이터 발신자** - 수신자로부터 대상 정보를 얻고 지정된 대상으로 로그 이벤트를 전송할 준비가 되었음을 CloudWatch Logs에 알립니다. 이 섹션의 나머지 부분에서는 가상 AWS 계정 번호가 111111111111인 로그 데이터 발신자가 표시됩니다.

  한 조직 내의 여러 계정에서 한 수신자 계정으로 로그를 보내려면 해당 조직의 모든 계정에서 수신자 계정으로 로그를 보낼 수 있는 권한을 부여하는 정책을 만들 수 있습니다. 각 발신자 계정에 대해 별도의 구독 필터를 설정해야 합니다.
+ **로그 데이터 수신자** - Amazon Kinesis Data Streams 스트림을 캡슐화하는 대상을 설정하고 CloudWatch Logs에 수신자가 로그 데이터를 수신하고 싶다는 사실을 알립니다. 그런 다음 수신자는 이 대상에 대한 정보를 발신자와 공유합니다. 이 섹션의 나머지 부분에서는 로그 데이터 수신자가 가상 AWS 계정 번호 999999999999로 표시됩니다.

교차 계정 사용자로부터 로그 이벤트 수신을 시작하기 위해 로그 데이터 수신자는 먼저 CloudWatch Logs 대상을 생성합니다. 각 대상은 다음과 같은 키 요소로 이루어져 있습니다.

**대상 이름**  
생성하고자 하는 대상의 이름.

**대상 ARN**  
구독 피드의 대상으로 사용할 리소스의 Amazon AWS 리소스 이름(ARN)입니다.

**역할 ARN**  
선택한 스트림에 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 AWS Identity and Access Management (IAM) 역할입니다.

**액세스 정책**  
대상에 쓰기 권한이 허용된 사용자들에게 적용되는 IAM 정책 문서(JSON 형식, IAM 정책 문법을 사용해 작성)입니다.

**참고**  
로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상이 가리키는 AWS 리소스는 다른 리전에 위치할 수 있습니다. 다음 섹션의 예제에서는 모든 리전 관련 리소스가 미국 동부(버지니아 북부)에서 생성됩니다.

**Topics**
+ [새 교차 계정 구독 설정](Cross-Account-Log_Subscription-New-Account.md)
+ [기존 교차 계정 구독 업데이트](Cross-Account-Log_Subscription-Update-Account.md)

# 새 교차 계정 구독 설정
<a name="Cross-Account-Log_Subscription-New-Account"></a>

이러한 섹션의 단계에 따라 새 교차 계정 로그 구독을 설정합니다.

**Topics**
+ [1단계: 대상 생성](CreateDestination-Account.md)
+ [2단계: (조직을 사용하는 경우에만) IAM 역할 생성](CreateSubscriptionFilter-IAMrole-Account.md)
+ [3단계: 계정 수준 구독 필터 정책 생성](CreateSubscriptionFilter-Account.md)
+ [로그 이벤트의 흐름 검증](ValidateLogEventFlow-Account.md)
+ [런타임 시 대상 멤버십 수정](ModifyDestinationMembership-Account.md)

# 1단계: 대상 생성
<a name="CreateDestination-Account"></a>

**중요**  
이 절차의 모든 단계는 로그 데이터 수신자 계정에서 수행되어야 합니다.

이 예제에서 로그 데이터 수신자 계정의 AWS 계정 ID는 999999999999이고 로그 데이터 발신자 AWS 계정 ID는 111111111111입니다.

 이 예제에서는 RecipientStream이라는 Amazon Kinesis Data Streams 스트림과 CloudWatch Logs가 데이터를 쓸 수 있는 역할을 사용하여 대상을 생성합니다.

대상이 생성되면 CloudWatch Logs는 수신자 계정을 대신하여 대상에게 테스트 메시지를 전송합니다. 구독 필터가 나중에 활성화되면 CloudWatch Logs는 소스 계정을 대신하여 대상에게 로그 이벤트를 보냅니다.

**대상을 생성하려면**

1. 수신자 계정에서 Amazon Kinesis Data Streams에 대상 스트림을 생성합니다. 명령 프롬프트에서 다음과 같이 입력합니다.

   ```
   aws kinesis create-stream --stream-name "RecipientStream" --shard-count 1
   ```

1. 스트림이 활성 상태가 될 때까지 기다립니다. **aws kinesis describe-stream** 명령을 사용하여 **StreamDescription.StreamStatus** 속성을 확인할 수 있습니다. 또한 CloudWatch Logs의 이후 단계에서 필요할 수 있기 때문에 **StreamDescription.StreamARN** 값을 기록해 둡니다.

   ```
   aws kinesis describe-stream --stream-name "RecipientStream"
   {
     "StreamDescription": {
       "StreamStatus": "ACTIVE",
       "StreamName": "RecipientStream",
       "StreamARN": "arn:aws:kinesis:us-east-1:999999999999:stream/RecipientStream",
       "Shards": [
         {
           "ShardId": "shardId-000000000000",
           "HashKeyRange": {
             "EndingHashKey": "34028236692093846346337460743176EXAMPLE",
             "StartingHashKey": "0"
           },
           "SequenceNumberRange": {
             "StartingSequenceNumber": "4955113521868881845667950383198145878459135270218EXAMPLE"
           }
         }
       ]
     }
   }
   ```

   스트림이 활성 상태가 될 때까지 1\$12분 정도 기다려야 할 수 있습니다.

1. 스트림에 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 **\$1/TrustPolicyForCWL.json** 파일에서 신뢰 정책을 생성해야 합니다. 텍스트 편집기를 사용하여 이 정책 파일을 생성하고 IAM 콘솔은 사용하지 마세요.

   이 정책은 `sourceAccountId`를 지정하여 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키를 포함합니다. 첫 번째 직접 호출에서 소스 계정 ID를 아직 모르는 경우 소스 ARN 필드에 대상 ARN을 넣는 것이 좋습니다. 후속 직접 호출에서는 소스 ARN을 첫 번째 직접 호출에서 수집한 실제 소스 ARN으로 설정해야 합니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 단원을 참조하십시오.

   ```
   {
       "Statement": {
           "Effect": "Allow",
           "Principal": {
               "Service": "logs.amazonaws.com"
           },
           "Condition": {
               "StringLike": {
                   "aws:SourceArn": [
                       "arn:aws:logs:region:sourceAccountId:*",
                       "arn:aws:logs:region:recipientAccountId:*"
                   ]
               }
           },
           "Action": "sts:AssumeRole"
       }
   }
   ```

1. **aws iam create-role** 명령을 사용하여 신뢰 정책 파일을 지정하는 IAM 역할을 생성합니다. 이 또한 CloudWatch Logs의 이후 단계에서 필요할 수 있기 때문에 반환된 Role.Arn 값을 적어 둡니다.

   ```
   aws iam create-role \
   --role-name CWLtoKinesisRole \
   --assume-role-policy-document file://~/TrustPolicyForCWL.json
   
   {
       "Role": {
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Action": "sts:AssumeRole",
                   "Effect": "Allow",
                   "Condition": {
                       "StringLike": {
                           "aws:SourceArn": [
                               "arn:aws:logs:region:sourceAccountId:*",
                               "arn:aws:logs:region:recipientAccountId:*"
                           ]
                       }
                   },
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   }
               }
           },
           "RoleId": "AAOIIAH450GAB4HC5F431",
           "CreateDate": "2023-05-29T13:46:29.431Z",
           "RoleName": "CWLtoKinesisRole",
           "Path": "/",
           "Arn": "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 권한 정책을 **\$1/PermissionsForCWL.json** 파일로 생성합니다.

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "kinesis:PutRecord",
         "Resource": "arn:aws:kinesis:region:999999999999:stream/RecipientStream"
       }
     ]
   }
   ```

1. **aws iam put-role-policy** 명령을 사용하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy \
       --role-name CWLtoKinesisRole \
       --policy-name Permissions-Policy-For-CWL \
       --policy-document file://~/PermissionsForCWL.json
   ```

1. 스트림이 활성 상태이고 IAM 역할을 생성하고 나면 CloudWatch Logs 대상을 생성할 수 있습니다.

   1. 이 단계를 수행해도 액세스 정책이 대상에 연결되는 것은 아니며, 대상 생성을 완료하기 위한 두 단계 중 첫 번째 단계를 완료한 것일 뿐입니다. 페이로드에 반환되는 **DestinationArn**을 적어둡니다.

      ```
      aws logs put-destination \
          --destination-name "testDestination" \
          --target-arn "arn:aws:kinesis:region:999999999999:stream/RecipientStream" \
          --role-arn "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
      
      {
        "DestinationName" : "testDestination",
        "RoleArn" : "arn:aws:iam::999999999999:role/CWLtoKinesisRole",
        "DestinationArn" : "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
        "TargetArn" : "arn:aws:kinesis:us-east-1:999999999999:stream/RecipientStream"
      }
      ```

   1. 7a 단계를 완료한 후 로그 데이터 수신자 계정에서 액세스 정책을 대상과 연결합니다. 이 정책은 **logs:PutSubscriptionFilter** 작업을 지정해야 하며, 발신자 계정에 대상에 액세스할 권한을 부여합니다.

      이 정책은 로그를 전송하는 AWS 계정에 권한을 부여합니다. 정책에서 이 계정 하나만 지정할 수 있으며, 또는 발신자 계정이 조직의 구성원인 경우 정책은 해당 조직의 조직 ID를 지정할 수 있습니다. 이렇게 하면 정책 하나만 생성하여 한 조직의 여러 계정이 이 대상 계정으로 로그를 보내도록 할 수 있습니다.

      텍스트 편집기를 사용하여 이름이 `~/AccessPolicy.json`이고 다음 정책 명령문 중 하나를 포함한 파일을 생성합니다.

      이 첫 번째 예제 정책은 ID가 `o-1234567890`인 조직의 모든 계정이 수신자 계정으로 로그를 보내도록 허용합니다.

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "",
                  "Effect": "Allow",
                  "Principal": "*",
                  "Action": [
                      "logs:PutSubscriptionFilter",
                      "logs:PutAccountPolicy"
                  ],
                  "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
                  "Condition": {
                      "StringEquals": {
                          "aws:PrincipalOrgID": [
                              "o-1234567890"
                          ]
                      }
                  }
              }
          ]
      }
      ```

------

      다음 예에서는 로그 데이터 발신자 계정(111111111111)에서만 로그 데이터 수신자 계정으로 로그를 보내도록 허용합니다.

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Sid": "",
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": "111111111111"
                  },
                  "Action": [
                      "logs:PutSubscriptionFilter",
                      "logs:PutAccountPolicy"
                  ],
                  "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination"
              }
          ]
      }
      ```

------

   1. 이전 단계에서 생성한 정책을 대상에 연결합니다.

      ```
      aws logs put-destination-policy \
          --destination-name "testDestination" \
          --access-policy file://~/AccessPolicy.json
      ```

      이 액세스 정책을 사용하면 ID가 111111111111인 AWS 계정의 사용자가 ARN arn:aws:logs:region::destination:testDestination인 대상에 대해 **PutSubscriptionFilter**를 호출할 수 있습니다.**999999999999 testDestination 다른 사용자가 이 대상에 대해 PutSubscriptionFilter를 직접 호출하려는 시도는 모두 거부됩니다.

      액세스 정책에 대한 사용자 권한의 유효성을 검사하려면 *IAM 사용 설명서*의 [정책 검사기 사용](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies_policy-validator.html)을 참조하세요.

작업을 마쳤으면 교차 계정 권한 AWS Organizations 에를 사용하는 경우의 단계를 따릅니다[2단계: (조직을 사용하는 경우에만) IAM 역할 생성](CreateSubscriptionFilter-IAMrole-Account.md). Organizations를 사용하는 대신 다른 계정에 직접 권한을 부여하는 경우 해당 단계를 건너뛰고 [3단계: 계정 수준 구독 필터 정책 생성](CreateSubscriptionFilter-Account.md) 단계로 넘어갑니다.

# 2단계: (조직을 사용하는 경우에만) IAM 역할 생성
<a name="CreateSubscriptionFilter-IAMrole-Account"></a>

이전 섹션에서 `111111111111` 계정이 속한 조직에 권한을 부여하는 액세스 정책을 사용하여 대상을 생성한 경우 `111111111111` 계정에 직접 권한을 부여하는 대신 이 섹션의 단계를 따릅니다. 그렇지 않다면 [3단계: 계정 수준 구독 필터 정책 생성](CreateSubscriptionFilter-Account.md) 단계로 건너뛰어도 됩니다.

이 섹션의 단계에서는 CloudWatch가 수신자 대상에 대한 구독 필터를 생성할 수 있는 권한이 발신자 계정에 있는지를 가정하고 검증할 수 있는 IAM 역할을 생성합니다.

발신자 계정에서 이 섹션의 단계를 수행합니다. 역할은 발신자 계정에 있어야 하며 구독 필터에서 이 역할의 ARN을 지정합니다. 이 예제에서 발신자 계정은 `111111111111`입니다.

**를 사용하여 교차 계정 로그 구독에 필요한 IAM 역할을 생성하려면 AWS Organizations**

1. `/TrustPolicyForCWLSubscriptionFilter.json` 파일에 다음 트러스트 정책을 생성합니다. 텍스트 편집기를 사용하여 이 정책 파일을 생성하고, IAM 콘솔은 사용하지 마세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole"
     }
   }
   ```

1. 이 정책을 사용하는 IAM 역할을 생성합니다. 명령에 의해 반환되는 `Arn` 값은 이 절차의 뒷부분에 필요하므로 메모해 둡니다. 이 예제에서 생성하는 역할의 이름으로는 `CWLtoSubscriptionFilterRole`을 사용합니다.

   ```
   aws iam create-role \ 
        --role-name CWLtoSubscriptionFilterRole \ 
        --assume-role-policy-document file://~/TrustPolicyForCWLSubscriptionFilter.json
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 다음 권한 정책을 이름이 `~/PermissionsForCWLSubscriptionFilter.json`인 파일로 생성합니다.

      ```
      { 
          "Statement": [ 
              { 
                  "Effect": "Allow", 
                  "Action": "logs:PutLogEvents", 
                  "Resource": "arn:aws:logs:region:111111111111:log-group:LogGroupOnWhichSubscriptionFilterIsCreated:*" 
              } 
          ] 
      }
      ```

   1. 다음 명령을 입력하여 방금 생성한 권한 정책을 2단계에서 생성한 역할에 연결합니다.

      ```
      aws iam put-role-policy  
          --role-name CWLtoSubscriptionFilterRole  
          --policy-name Permissions-Policy-For-CWL-Subscription-filter 
          --policy-document file://~/PermissionsForCWLSubscriptionFilter.json
      ```

작업을 마쳤으면 [3단계: 계정 수준 구독 필터 정책 생성](CreateSubscriptionFilter-Account.md) 단계로 넘어갑니다.

# 3단계: 계정 수준 구독 필터 정책 생성
<a name="CreateSubscriptionFilter-Account"></a>

대상을 생성하고 나면 로그 데이터 수신자 계정에서 다른 AWS 계정이 로그 이벤트를 동일한 대상으로 전송할 수 있도록 대상 ARN(arn:aws:logs:us-east-1:999999999999:destination:testDestination)을 이들과 공유할 수 있습니다. 그러면 이러한 다른 전송 계정 사용자는 이 대상에 해당되는 로그 그룹에 대한 구독 필터를 생성합니다. 그 즉시 구독 필터는 실시간으로 선택한 로그 그룹에서 지정된 스트림으로 로그 데이터를 이동시키기 시작합니다.

**참고**  
전체 조직에 구독 필터에 대한 권한을 부여하는 경우 [2단계: (조직을 사용하는 경우에만) IAM 역할 생성](CreateSubscriptionFilter-IAMrole-Account.md)에서 생성한 IAM 역할의 ARN을 사용해야 합니다.

다음 예제에서는 전송 계정에 계정 수준 구독 필터 정책이 생성됩니다. 필터는 발신자 계정 `111111111111`과 연결되어 필터 및 선택 기준과 일치하는 모든 로그 이벤트가 이전에 생성한 대상으로 전달됩니다. 이 대상에서는 'RecipientStream'이라는 스트림을 캡슐화합니다.

`selection-criteria` 필드는 선택 사항이지만 구독 필터에서 무한 로그 재귀를 일으킬 수 있는 로그 그룹을 제외하는 데 중요합니다. 이 문제 및 제외할 로그 그룹 결정에 대한 자세한 내용은 [로그 재귀 방지](Subscriptions-recursion-prevention.md)을 참조하세요. 현재 NOT IN은 `selection-criteria`에 지원되는 유일한 연산자입니다.

```
aws logs put-account-policy \
    --policy-name "CrossAccountStreamsExamplePolicy" \
    --policy-type "SUBSCRIPTION_FILTER_POLICY" \
    --policy-document '{"DestinationArn":"arn:aws:logs:region:999999999999:destination:testDestination", "FilterPattern": "", "Distribution": "Random"}' \
    --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
    --scope "ALL"
```

발신자 계정의 로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상은 다른 리전에 있는 Amazon Kinesis Data Streams 스트림과 같은 AWS 리소스를 가리킬 수 있습니다.

# 로그 이벤트의 흐름 검증
<a name="ValidateLogEventFlow-Account"></a>

계정 수준 구독 필터 정책을 생성하고 나면 CloudWatch Logs가 모든 수신 로그 이벤트 중에서 필터 패턴 및 선택 기준과 일치하는 이벤트를 "**RecipientStream**"이라는 대상 스트림 내에서 캡슐화된 스트림으로 전달합니다. 대상 소유자는 **aws kinesis get-shard-iterator** 명령을 사용하여 Amazon Kinesis Data Streams 샤드를 캡처하고 **aws kinesis get-records** 명령을 사용하여 일부 Amazon Kinesis Data Streams 레코드를 가져와서이 문제가 발생하고 있는지 확인할 수 있습니다.

```
aws kinesis get-shard-iterator \
      --stream-name RecipientStream \
      --shard-id shardId-000000000000 \
      --shard-iterator-type TRIM_HORIZON

{
    "ShardIterator":
    "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiKEXAMPLE"
}

aws kinesis get-records \
      --limit 10 \
      --shard-iterator
      "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiKEXAMPLE"
```

**참고**  
Amazon Kinesis Data Streams가 데이터를 반환하기 전에 `get-records` 명령을 몇 번 다시 실행해야 할 수 있습니다.

Amazon Kinesis Data Streams 레코드 배열이 포함된 응답이 표시됩니다. Amazon Kinesis Data Streams 레코드의 데이터 속성은 gzip 형식으로 압축된 다음 base64로 인코딩됩니다. 다음 Unix 명령을 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

```
echo -n "<Content of Data>" | base64 -d | zcat
```

디코딩 및 압축 해제된 base64 데이터는 다음 구조를 가진 JSON으로 포맷됩니다.

```
{
    "owner": "111111111111",
    "logGroup": "CloudTrail/logs",
    "logStream": "111111111111_CloudTrail/logs_us-east-1",
    "subscriptionFilters": [
        "RecipientStream"
    ],
    "messageType": "DATA_MESSAGE",
    "logEvents": [
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        },
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        },
        {
            "id": "3195310660696698337880902507980421114328961542429EXAMPLE",
            "timestamp": 1432826855000,
            "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}"
        }
    ]
}
```

데이터 구조에서 키 요소는 다음과 같습니다.

**messageType**  
데이터 메시지는 'DATA\$1MESSAGE' 유형을 사용합니다. CloudWatch Logs는 주로 대상에 연결할 수 있는지 확인하기 위해 "CONTROL\$1MESSAGE" 유형의 Amazon Kinesis Data Streams 레코드를 내보낼 수 있습니다.

**owner**  
발신 로그 데이터의 AWS 계정 ID입니다.

**logGroup**  
원본 로그 데이터의 로그 그룹 이름.

**logStream**  
원본 로그 데이터의 로그 스트림 이름.

**subscriptionFilters**  
원본 로그 데이터과 일치한 구독 필터 이름 목록입니다.

**logEvents**  
로그 이벤트 레코드의 배열로 표현되는 실제 로그 데이터. 'ID' 속성은 모든 로그 이벤트의 고유 식별자입니다.

**policyLevel**  
정책이 적용된 수준. 'ACCOUNT\$1LEVEL\$1POLICY'는 계정 수준 구독 필터 정책의 `policyLevel`입니다.

# 런타임 시 대상 멤버십 수정
<a name="ModifyDestinationMembership-Account"></a>

소유된 대상에서 몇몇 사용자의 멤버십을 추가 또는 제거해야 하는 상황에 직면할 수 있습니다. 새 액세스 정책과 함께 대상에 `put-destination-policy` 명령을 사용할 수 있습니다. 다음 예제에서는 이전에 추가한 계정인 **111111111111**이 추가적인 로그 데이터 전송을 중단하고 계정 **222222222222**가 활성화됩니다.

1. 대상 **testDestination**에 현재 연결된 정책을 가져와서 **AccessPolicy**를 적어둡니다.

   ```
   aws logs describe-destinations \
       --destination-name-prefix "testDestination"
   
   {
    "Destinations": [
      {
        "DestinationName": "testDestination",
        "RoleArn": "arn:aws:iam::999999999999:role/CWLtoKinesisRole",
        "DestinationArn": "arn:aws:logs:region:999999999999:destination:testDestination",
        "TargetArn": "arn:aws:kinesis:region:999999999999:stream/RecipientStream",
        "AccessPolicy": "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Sid\": \"\", \"Effect\": \"Allow\", \"Principal\": {\"AWS\": \"111111111111\"}, \"Action\": \"logs:PutSubscriptionFilter\", \"Resource\": \"arn:aws:logs:region:999999999999:destination:testDestination\"}] }"
      }
    ]
   }
   ```

1. 계정 **111111111111**이 중단되고 계정 **222222222222**가 활성화되었음을 반영하도록 이 정책을 업데이트합니다. **\$1/NewAccessPolicy.json** 파일에 이 정책을 저장합니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "222222222222"
               },
               "Action": [
                   "logs:PutSubscriptionFilter",
                   "logs:PutAccountPolicy"
               ],
               "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination"
           }
       ]
   }
   ```

------

1. **PutDestinationPolicy**를 직접 호출하여 **NewAccessPolicy.json** 파일에 정의된 정책을 대상에 연결합니다.

   ```
   aws logs put-destination-policy \
   --destination-name "testDestination" \
   --access-policy file://~/NewAccessPolicy.json
   ```

   이렇게 하면 계정 ID **111111111111**에서 로그 이벤트가 비활성화됩니다. 계정 ID **222222222222**에서 나온 로그 이벤트는 계정 **222222222222** 의 소유자가 구독 필터를 생성하고 나면 그 즉시 대상으로 이동하기 시작합니다.

# 기존 교차 계정 구독 업데이트
<a name="Cross-Account-Log_Subscription-Update-Account"></a>

현재 대상 계정이 특정 발신자 계정에만 권한을 부여하는 교차 계정 로그 구독이 있고 대상 계정이 조직의 모든 계정에 대한 액세스 권한을 부여하도록 이 구독을 업데이트하려는 경우 이 섹션의 단계를 따릅니다.

**Topics**
+ [1단계: 구독 필터 업데이트](Cross-Account-Log_Subscription-Update-filter-Account.md)
+ [2단계: 기존 대상 액세스 정책 업데이트](Cross-Account-Log_Subscription-Update-policy-Account.md)

# 1단계: 구독 필터 업데이트
<a name="Cross-Account-Log_Subscription-Update-filter-Account"></a>

**참고**  
이 단계는 [AWS 서비스에서 로깅 활성화](AWS-logs-and-resource-policy.md)에 나열된 서비스에서 생성된 로그에 대한 교차 계정 구독에만 필요합니다. 해당 로그 그룹 중 하나에서 생성된 로그로 작업하지 않는 경우 [2단계: 기존 대상 액세스 정책 업데이트](Cross-Account-Log_Subscription-Update-policy-Account.md) 섹션으로 건너뛸 수 있습니다.

경우에 따라 대상 계정으로 로그를 보내는 모든 발신자 계정의 구독 필터를 업데이트해야 합니다. 업데이트에는 IAM 역할이 추가됩니다. IAM 역할은 CloudWatch에서 발신자 계정이 수신자 계정에 로그를 보낼 수 있는 권한이 있는지를 가정하고 검증할 수 있습니다.

교차 계정 구독 권한에 대해 조직 ID를 사용하도록 업데이트하려는 모든 발신자 계정에 대해서는 이 섹션의 단계를 따릅니다.

이 섹션의 예제에서 두 개의 `111111111111` 계정 및 `222222222222` 계정은 `999999999999` 계정에 로그를 전송하기 위해 생성된 구독 필터를 이미 가지고 있습니다. 기존 구독 필터 값은 다음과 같습니다.

```
## Existing Subscription Filter parameter values
{
    "DestinationArn": "arn:aws:logs:region:999999999999:destination:testDestination",
    "FilterPattern": "{$.userIdentity.type = Root}",
    "Distribution": "Random"
}
```

현재 구독 필터 파라미터 값을 찾아야 하는 경우 다음 명령을 입력합니다.

```
aws logs describe-account-policies \
--policy-type "SUBSCRIPTION_FILTER_POLICY" \
--policy-name "CrossAccountStreamsExamplePolicy"
```

**교차 계정 로그 권한에 대한 조직 ID 사용을 시작하도록 구독 필터 업데이트**

1. `~/TrustPolicyForCWL.json` 파일에 다음 트러스트 정책을 생성합니다. 텍스트 편집기를 사용하여 이 정책 파일을 생성하고, IAM 콘솔은 사용하지 마세요.

   ```
   {
     "Statement": {
       "Effect": "Allow",
       "Principal": { "Service": "logs.amazonaws.com" },
       "Action": "sts:AssumeRole"
     }
   }
   ```

1. 이 정책을 사용하는 IAM 역할을 생성합니다. 명령에 의해 반환되는 `Arn` 값의 `Arn` 값은 이 절차의 뒷부분에 필요하므로 메모해 둡니다. 이 예제에서 생성하는 역할의 이름으로는 `CWLtoSubscriptionFilterRole`을 사용합니다.

   ```
   aws iam create-role 
       \ --role-name CWLtoSubscriptionFilterRole 
       \ --assume-role-policy-document file://~/TrustPolicyForCWL.json
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 다음 권한 정책을 이름이 `/PermissionsForCWLSubscriptionFilter.json`인 파일로 생성합니다.

      ```
      { 
          "Statement": [ 
              { 
                  "Effect": "Allow", 
                  "Action": "logs:PutLogEvents", 
                  "Resource": "arn:aws:logs:region:111111111111:log-group:LogGroupOnWhichSubscriptionFilterIsCreated:*" 
              } 
          ] 
      }
      ```

   1. 다음 명령을 입력하여 방금 생성한 권한 정책을 2단계에서 생성한 역할에 연결합니다.

      ```
      aws iam put-role-policy 
          --role-name CWLtoSubscriptionFilterRole 
          --policy-name Permissions-Policy-For-CWL-Subscription-filter 
          --policy-document file://~/PermissionsForCWLSubscriptionFilter.json
      ```

1. 다음 명령을 입력하여 구독 필터 정책을 업데이트합니다.

   ```
   aws logs put-account-policy \
       --policy-name "CrossAccountStreamsExamplePolicy" \
       --policy-type "SUBSCRIPTION_FILTER_POLICY" \
       --policy-document '{"DestinationArn":"arn:aws:logs:region:999999999999:destination:testDestination", "FilterPattern": "{$.userIdentity.type = Root}", "Distribution": "Random"}' \
       --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
       --scope "ALL"
   ```

# 2단계: 기존 대상 액세스 정책 업데이트
<a name="Cross-Account-Log_Subscription-Update-policy-Account"></a>

모든 발신자 계정에서 구독 필터를 업데이트한 후, 수신자 계정에서 대상 액세스 정책을 업데이트할 수 있습니다.

다음 예제에서 수신자 계정은 `999999999999`이며 대상의 이름은 `testDestination`입니다.

업데이트를 통해 ID가 `o-1234567890`인 조직의 모든 계정이 수신자 계정으로 로그를 보낼 수 있습니다. 구독 필터가 생성된 계정만이 실제로 수신자 계정에 로그를 보냅니다.

**수신자 계정의 대상 액세스 정책을 업데이트하여 권한에 대한 조직 ID 사용**

1. 수신자 계정에서 텍스트 편집기를 사용하여 다음 내용을 포함한 `~/AccessPolicy.json` 파일을 생성합니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": "*",
               "Action": [
                   "logs:PutSubscriptionFilter",
                   "logs:PutAccountPolicy"
               ],
               "Resource": "arn:aws:logs:us-east-1:999999999999:destination:testDestination",
               "Condition": {
                   "StringEquals": {
                       "aws:PrincipalOrgID": [
                           "o-1234567890"
                       ]
                   }
               }
           }
       ]
   }
   ```

------

1. 다음 명령을 입력하여 방금 생성한 정책을 기존 대상에 연결합니다. 특정 AWS 계정 ID를 나열하는 액세스 정책 대신 조직 IDs로 액세스 정책을 사용하도록 대상을 업데이트하려면 `force` 파라미터를 포함합니다.
**주의**  
에 나열된 AWS 서비스에서 전송한 로그로 작업[AWS 서비스에서 로깅 활성화](AWS-logs-and-resource-policy.md)하는 경우이 단계를 수행하기 전에 먼저에 설명된 대로 모든 발신자 계정의 구독 필터를 업데이트해야 합니다[1단계: 구독 필터 업데이트](Cross-Account-Log_Subscription-Update-filter-Account.md).

   ```
   aws logs put-destination-policy 
       \ --destination-name "testDestination" 
       \ --access-policy file://~/AccessPolicy.json
       \ --force
   ```

# Firehose를 사용한 교차 계정 교차 리전 계정 수준 구독
<a name="CrossAccountSubscriptions-Firehose-Account"></a>

계정에서 로그 데이터를 공유하려면 로그 데이터 발신자 및 수신자를 설정해야 합니다.
+ **로그 데이터 발신자** - 수신자로부터 대상 정보를 얻고 지정된 대상으로 로그 이벤트를 전송할 준비가 되었음을 CloudWatch Logs에 알립니다. 이 섹션의 나머지 부분에서는 가상 AWS 계정 번호가 111111111111인 로그 데이터 발신자가 표시됩니다.
+ **로그 데이터 수신자** - Amazon Kinesis Data Streams 스트림을 캡슐화하는 대상을 설정하고 CloudWatch Logs에 수신자가 로그 데이터를 수신하고 싶다는 사실을 알립니다. 그런 다음 수신자는 이 대상에 대한 정보를 발신자와 공유합니다. 이 섹션의 나머지 부분에서는 가상 AWS 계정 번호가 222222222222인 로그 데이터 수신자가 표시됩니다.

이 섹션의 예에서는 Amazon S3 스토리지와 함께 Firehose 전송 스트림을 사용합니다. 다른 설정을 사용하여 Firehose 전송 스트림을 설정할 수도 있습니다. 자세한 내용은 [Creating a Firehose Delivery Stream](https://docs.aws.amazon.com/firehose/latest/dev/basic-create.html)을 참조하세요.

**참고**  
로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상이 가리키는 AWS 리소스는 다른 리전에 위치할 수 있습니다.

**참고**  
 ***동일한 계정*** 및 ***교차 리전*** 전송 스트림에 대한 Firehose 구독 필터가 지원됩니다.

**Topics**
+ [1단계: Firehose 전송 스트림 생성](CreateFirehoseStream-Account.md)
+ [2단계: 대상 생성](CreateFirehoseStreamDestination-Account.md)
+ [3단계: 계정 수준 구독 필터 정책 생성](CreateSubscriptionFilterFirehose-Account.md)
+ [로그 이벤트 흐름 검증](ValidateLogEventFlowFirehose-Account.md)
+ [런타임 시 대상 멤버십 수정](ModifyDestinationMembershipFirehose-Account.md)

# 1단계: Firehose 전송 스트림 생성
<a name="CreateFirehoseStream-Account"></a>

**중요**  
 다음 단계를 완료하기 전에 Firehose가 Amazon S3 버킷에 액세스할 수 있도록 액세스 정책을 사용해야 합니다. 자세한 내용은 *Amazon Data Firehose 개발자 가이드*의 [액세스 제어](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html#using-iam-s3)를 참조하세요.  
 이 섹션(1단계)의 모든 단계는 로그 데이터 수신자 계정에서 수행해야 합니다.  
 미국 동부(버지니아 북부)가 다음 샘플 명령에 사용됩니다. 이 리전을 배포에 적합한 리전으로 바꿉니다.

**대상으로 사용할 Firehose 전송 스트림을 생성하려면**

1. Amazon S3 버킷 생성:

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-bucket --create-bucket-configuration LocationConstraint=us-east-1
   ```

1. 버킷에 데이터를 입력하는 데 필요한 권한을 Firehose에 부여하는 IAM 역할을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 `~/TrustPolicyForFirehose.json` 파일에 신뢰 정책을 생성합니다.

      ```
      { "Statement": { "Effect": "Allow", "Principal": { "Service": "firehose.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId":"222222222222" } } } }
      ```

   1. IAM 역할을 생성하여 방금 생성한 신뢰 정책 파일을 지정합니다.

      ```
      aws iam create-role \ 
          --role-name FirehosetoS3Role \ 
          --assume-role-policy-document file://~/TrustPolicyForFirehose.json
      ```

   1. 이 명령의 출력은 다음과 비슷합니다. 역할 이름과 역할 ARN을 기록해둡니다.

      ```
      {
          "Role": {
              "Path": "/",
              "RoleName": "FirehosetoS3Role",
              "RoleId": "AROAR3BXASEKW7K635M53",
              "Arn": "arn:aws:iam::222222222222:role/FirehosetoS3Role",
              "CreateDate": "2021-02-02T07:53:10+00:00",
              "AssumeRolePolicyDocument": {
                  "Statement": {
                      "Effect": "Allow",
                      "Principal": {
                          "Service": "firehose.amazonaws.com"
                      },
                      "Action": "sts:AssumeRole",
                      "Condition": {
                          "StringEquals": {
                              "sts:ExternalId": "222222222222"
                          }
                      }
                  }
              }
          }
      }
      ```

1. Firehose가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다.

   1. 먼저 텍스트 편집기를 사용하여 다음 권한 정책을 이름이 `~/PermissionsForFirehose.json`인 파일로 생성합니다. 사용 사례에 따라 이 파일에 권한을 더 추가해야 할 수도 있습니다.

      ```
      {
          "Statement": [{
              "Effect": "Allow",
              "Action": [
                  "s3:PutObject",
                  "s3:PutObjectAcl",
                  "s3:ListBucket"
              ],
              "Resource": [
                  "arn:aws:s3:::amzn-s3-demo-bucket",
                  "arn:aws:s3:::amzn-s3-demo-bucket/*"
              ]
          }]
      }
      ```

   1. 다음 명령을 입력하여 방금 생성한 권한 정책을 IAM 역할에 연결합니다.

      ```
      aws iam put-role-policy --role-name FirehosetoS3Role --policy-name Permissions-Policy-For-Firehose-To-S3 --policy-document file://~/PermissionsForFirehose.json
      ```

1. 다음 명령을 입력하여 Firehose 전송 스트림을 생성합니다. *my-role-arn* 및 *amzn-s3-demo-bucket2-arn*을 배포에 올바른 값으로 바꿉니다.

   ```
   aws firehose create-delivery-stream \
      --delivery-stream-name 'my-delivery-stream' \
      --s3-destination-configuration \
     '{"RoleARN": "arn:aws:iam::222222222222:role/FirehosetoS3Role", "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket"}'
   ```

   출력은 다음과 비슷하게 보여야 합니다.

   ```
   {
       "DeliveryStreamARN": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream"
   }
   ```

# 2단계: 대상 생성
<a name="CreateFirehoseStreamDestination-Account"></a>

**중요**  
이 절차의 모든 단계는 로그 데이터 수신자 계정에서 수행되어야 합니다.

대상이 생성되면 CloudWatch Logs는 수신자 계정을 대신하여 대상에게 테스트 메시지를 보냅니다. 구독 필터가 나중에 활성화되면 CloudWatch Logs는 소스 계정을 대신하여 대상에게 로그 이벤트를 보냅니다.

**대상을 생성하려면**

1. [1단계: Firehose 전송 스트림 생성](CreateFirehoseStream-Account.md)에서 생성한 Firehose 스트림이 활성화될 때까지 기다립니다. 다음 명령을 사용하여 **StreamDescription.StreamStatus** 속성을 확인할 수 있습니다.

   ```
   aws firehose describe-delivery-stream --delivery-stream-name "my-delivery-stream"
   ```

   또한 이후 단계에서 사용해야 하기 때문에 **DeliveryStreamDescription.DeliveryStreamARN** 값을 기록해 둡니다. 이 명령의 샘플 출력:

   ```
   {
       "DeliveryStreamDescription": {
           "DeliveryStreamName": "my-delivery-stream",
           "DeliveryStreamARN": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream",
           "DeliveryStreamStatus": "ACTIVE",
           "DeliveryStreamEncryptionConfiguration": {
               "Status": "DISABLED"
           },
           "DeliveryStreamType": "DirectPut",
           "VersionId": "1",
           "CreateTimestamp": "2021-02-01T23:59:15.567000-08:00",
           "Destinations": [
               {
                   "DestinationId": "destinationId-000000000001",
                   "S3DestinationDescription": {
                       "RoleARN": "arn:aws:iam::222222222222:role/FirehosetoS3Role",
                       "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket",
                       "BufferingHints": {
                           "SizeInMBs": 5,
                           "IntervalInSeconds": 300
                       },
                       "CompressionFormat": "UNCOMPRESSED",
                       "EncryptionConfiguration": {
                           "NoEncryptionConfig": "NoEncryption"
                       },
                       "CloudWatchLoggingOptions": {
                           "Enabled": false
                       }
                   },
                   "ExtendedS3DestinationDescription": {
                       "RoleARN": "arn:aws:iam::222222222222:role/FirehosetoS3Role",
                       "BucketARN": "arn:aws:s3:::amzn-s3-demo-bucket",
                       "BufferingHints": {
                           "SizeInMBs": 5,
                           "IntervalInSeconds": 300
                       },
                       "CompressionFormat": "UNCOMPRESSED",
                       "EncryptionConfiguration": {
                           "NoEncryptionConfig": "NoEncryption"
                       },
                       "CloudWatchLoggingOptions": {
                           "Enabled": false
                       },
                       "S3BackupMode": "Disabled"
                   }
               }
           ],
           "HasMoreDestinations": false
       }
   }
   ```

   전송 스트림이 활성 상태가 될 때까지 1\$12분 정도 기다려야 할 수 있습니다.

1. 전송 스트림이 활성 상태가 되면 Firehose 스트림으로 데이터를 입력하는 데 필요한 권한을 CloudWatch Logs에 부여하는 IAM 역할을 생성합니다. 먼저 **\$1/TrustPolicyForCWL.json** 파일에서 신뢰 정책을 생성해야 합니다. 텍스트 편집기를 사용하여 이 정책을 생성합니다. CloudWatch Logs 엔드포인트에 대한 자세한 내용은 [Amazon CloudWatch Logs 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/cwl_region.html)을 참조하세요.

   이 정책은 `sourceAccountId`를 지정하여 혼동된 대리자 보안 문제를 방지하는 데 도움이 되는 `aws:SourceArn` 글로벌 조건 컨텍스트 키를 포함합니다. 첫 번째 직접 호출에서 소스 계정 ID를 아직 모르는 경우 소스 ARN 필드에 대상 ARN을 넣는 것이 좋습니다. 후속 직접 호출에서는 소스 ARN을 첫 번째 직접 호출에서 수집한 실제 소스 ARN으로 설정해야 합니다. 자세한 내용은 [혼동된 대리자 방지](Subscriptions-confused-deputy.md) 단원을 참조하십시오.

   ```
   {
       "Statement": {
           "Effect": "Allow",
           "Principal": {
               "Service": "logs.amazonaws.com"
           },
           "Action": "sts:AssumeRole",
           "Condition": {
               "StringLike": {
                   "aws:SourceArn": [
                       "arn:aws:logs:region:sourceAccountId:*",
                       "arn:aws:logs:region:recipientAccountId:*"
                   ]
               }
           }
        }
   }
   ```

1. **aws iam create-role** 명령을 사용하여 IAM 역할을 생성해 방금 만든 신뢰 정책 파일을 지정합니다.

   ```
   aws iam create-role \
         --role-name CWLtoKinesisFirehoseRole \
         --assume-role-policy-document file://~/TrustPolicyForCWL.json
   ```

   다음은 샘플 출력입니다. 이후 단계에서 사용해야 하므로 반환된 `Role.Arn` 값을 메모해 둡니다.

   ```
   {
       "Role": {
           "Path": "/",
           "RoleName": "CWLtoKinesisFirehoseRole",
           "RoleId": "AROAR3BXASEKYJYWF243H",
           "Arn": "arn:aws:iam::222222222222:role/CWLtoKinesisFirehoseRole",
           "CreateDate": "2023-02-02T08:10:43+00:00",
           "AssumeRolePolicyDocument": {
               "Statement": {
                   "Effect": "Allow",
                   "Principal": {
                       "Service": "logs.amazonaws.com"
                   },
                   "Action": "sts:AssumeRole",
                   "Condition": {
                       "StringLike": {
                           "aws:SourceArn": [
                               "arn:aws:logs:region:sourceAccountId:*",
                               "arn:aws:logs:region:recipientAccountId:*"
                           ]
                       }
                   }
               }
           }
       }
   }
   ```

1. CloudWatch Logs가 계정에서 수행할 수 있는 작업을 정의하는 권한 정책을 생성합니다. 먼저 텍스트 편집기를 사용하여 권한 정책을 **\$1/PermissionsForCWL.json** 파일로 생성합니다.

   ```
   {
       "Statement":[
         {
           "Effect":"Allow",
           "Action":["firehose:*"],
           "Resource":["arn:aws:firehose:region:222222222222:*"]
         }
       ]
   }
   ```

1. 다음 명령을 입력하여 권한 정책을 역할에 연결합니다.

   ```
   aws iam put-role-policy --role-name CWLtoKinesisFirehoseRole --policy-name Permissions-Policy-For-CWL --policy-document file://~/PermissionsForCWL.json
   ```

1. Firehose 전송 스트림이 활성 상태이고 IAM 역할을 생성하고 나면 CloudWatch Logs 대상을 생성할 수 있습니다.

   1. 이 단계를 수행했다고 액세스 정책이 대상에 연결되는 것은 아니며, 대상 생성을 완료하기 위한 두 단계 중 첫 번째 단계일 뿐입니다. 페이로드에서 반환된 새 대상의 ARN은 이후 단계에서 `destination.arn`으로 사용할 것이므로 메모해 둡니다.

      ```
      aws logs put-destination \                                                       
          --destination-name "testFirehoseDestination" \
          --target-arn "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream" \
          --role-arn "arn:aws:iam::222222222222:role/CWLtoKinesisFirehoseRole"
      
      {
          "destination": {
              "destinationName": "testFirehoseDestination",
              "targetArn": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream",
              "roleArn": "arn:aws:iam::222222222222:role/CWLtoKinesisFirehoseRole",
              "arn": "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"}
      }
      ```

   1. 이전 단계를 완료한 후 로그 데이터 수신자 계정(222222222222)에서 액세스 정책을 대상과 연결합니다. 이 정책을 사용하면 로그 데이터 발신자 계정(111111111111)이 로그 데이터 수신자 계정(222222222222)만의 대상에 액세스할 수 있습니다. 텍스트 편집기를 사용하여 이 정책을`~/AccessPolicy.json` 파일에 저장할 수 있습니다.

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement" : [
          {
            "Sid" : "",
            "Effect" : "Allow",
            "Principal" : {
              "AWS" : "111111111111"
            },
            "Action" : ["logs:PutSubscriptionFilter","logs:PutAccountPolicy"],
            "Resource" : "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"
          }
        ]
      }
      ```

------

   1. 이렇게 하면 대상에 대해 쓰기 액세스 권한을 가진 사람을 정의하는 정책이 생성됩니다. 이 정책은 대상에 액세스하기 위해 `logs:PutSubscriptionFilter` 및 `logs:PutAccountPolicy` 작업을 지정해야 합니다. 교차 계정 사용자는 `PutSubscriptionFilter` 및 `PutAccountPolicy` 작업을 사용하여 대상에 로그 이벤트를 전송합니다.

      ```
      aws logs put-destination-policy \
          --destination-name "testFirehoseDestination" \
          --access-policy file://~/AccessPolicy.json
      ```

# 3단계: 계정 수준 구독 필터 정책 생성
<a name="CreateSubscriptionFilterFirehose-Account"></a>

이 예제에서는 111111111111인 전송 계정으로 전환합니다. 이제 전송 계정에서 계정 수준 구독 필터 정책을 생성합니다. 이 예제에서 필터는 두 로그 그룹을 제외한 모든 로그 그룹에서 `ERROR` 문자열이 포함된 모든 로그 이벤트를 이전에 생성한 대상으로 전송하도록 합니다.

```
aws logs put-account-policy \
    --policy-name "CrossAccountFirehoseExamplePolicy" \
    --policy-type "SUBSCRIPTION_FILTER_POLICY" \
    --policy-document '{"DestinationArn":"arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination", "FilterPattern": "{$.userIdentity.type = AssumedRole}", "Distribution": "Random"}' \
    --selection-criteria 'LogGroupName NOT IN ["LogGroupToExclude1", "LogGroupToExclude2"]' \
    --scope "ALL"
```

전송 계정의 로그 그룹과 대상은 동일한 AWS 리전에 있어야 합니다. 그러나 대상은 다른 리전에 있는 Firehose 스트림과 같은 AWS 리소스를 가리킬 수 있습니다.

# 로그 이벤트 흐름 검증
<a name="ValidateLogEventFlowFirehose-Account"></a>

구독 필터를 생성하고 나면 CloudWatch Logs는 모든 수신 로그 이벤트 중에서 필터 패턴 및 선택 기준과 일치하는 이벤트를 Firehose 전송 스트림으로 전달합니다. Firehose 전송 스트림에 설정된 시간 버퍼 간격에 따라 Amazon S3 버킷에 데이터가 나타나기 시작합니다. 충분한 시간이 지나고 나면 Amazon S3 버킷을 확인하여 데이터를 확인할 수 있습니다. 버킷을 확인하려면 다음 명령을 입력합니다.

```
aws s3api list-objects --bucket 'amzn-s3-demo-bucket' 
```

해당 명령은 다음과 비슷하게 출력됩니다.

```
{
    "Contents": [
        {
            "Key": "2021/02/02/08/my-delivery-stream-1-2021-02-02-08-55-24-5e6dc317-071b-45ba-a9d3-4805ba39c2ba",
            "LastModified": "2023-02-02T09:00:26+00:00",
            "ETag": "\"EXAMPLEa817fb88fc770b81c8f990d\"",
            "Size": 198,
            "StorageClass": "STANDARD",
            "Owner": {
                "DisplayName": "firehose+2test",
                "ID": "EXAMPLE27fd05889c665d2636218451970ef79400e3d2aecca3adb1930042e0"
            }
        }
    ]
}
```

다음 명령을 입력하여 버킷에서 특정 객체를 검색할 수 있습니다. 이전 명령에서 찾은 값으로 `key`의 값을 바꿉니다.

```
aws s3api get-object --bucket 'amzn-s3-demo-bucket' --key '2021/02/02/08/my-delivery-stream-1-2021-02-02-08-55-24-5e6dc317-071b-45ba-a9d3-4805ba39c2ba' testfile.gz
```

Amazon S3 객체의 데이터는 gzip 형식으로 압축됩니다. 다음 명령 중 하나를 사용하여 명령 줄에서 원시 데이터를 검토할 수 있습니다.

Linux:

```
zcat testfile.gz
```

macOS:

```
zcat <testfile.gz
```

# 런타임 시 대상 멤버십 수정
<a name="ModifyDestinationMembershipFirehose-Account"></a>

소유한 대상에서 로그 발신자를 추가 또는 제거해야 하는 상황에 직면할 수 있습니다. 새 액세스 정책에서는 대상에 대해 **PutDestinationPolicy** 및 `PutAccountPolicy` 작업을 사용할 수 있습니다. 다음 예제에서는 이전에 추가한 계정인 **111111111111**이 추가적인 로그 데이터 전송을 중단하고 계정 **333333333333**이 활성화됩니다.

1. 대상 **testDestination**에 현재 연결된 정책을 가져와서 **AccessPolicy**를 적어둡니다.

   ```
   aws logs describe-destinations \
       --destination-name-prefix "testFirehoseDestination"
   ```

   반환된 데이터는 다음과 같을 수 있습니다.

   ```
   {
       "destinations": [
           {
               "destinationName": "testFirehoseDestination",
               "targetArn": "arn:aws:firehose:us-east-1:222222222222:deliverystream/my-delivery-stream",
               "roleArn": "arn:aws:iam:: 222222222222:role/CWLtoKinesisFirehoseRole",
               "accessPolicy": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [\n    {\n      \"Sid\" : \"\",\n      \"Effect\" : \"Allow\",\n      \"Principal\" : {\n        \"AWS\" : \"111111111111 \"\n      },\n      \"Action\" : \"logs:PutSubscriptionFilter\",\n      \"Resource\" : \"arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination\"\n    }\n  ]\n}\n\n",
               "arn": "arn:aws:logs:us-east-1: 222222222222:destination:testFirehoseDestination",
               "creationTime": 1612256124430
           }
       ]
   }
   ```

1. 계정 **111111111111**이 중단되고 계정 **333333333333**이 활성화되었음을 반영하도록 이 정책을 업데이트합니다. **\$1/NewAccessPolicy.json** 파일에 이 정책을 저장합니다.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement" : [
       {
         "Sid" : "",
         "Effect" : "Allow",
         "Principal" : {
           "AWS" : "333333333333 "
         },
         "Action" : ["logs:PutSubscriptionFilter","logs:PutAccountPolicy"],
         "Resource" : "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"
       }
     ]
   }
   ```

------

1. 다음 명령을 사용하여 **NewAccessPolicy.json** 파일에 정의된 정책을 대상과 연결합니다.

   ```
   aws logs put-destination-policy \
       --destination-name "testFirehoseDestination" \                                                                              
       --access-policy file://~/NewAccessPolicy.json
   ```

   이렇게 하면 계정 ID **111111111111**에서 로그 이벤트가 비활성화됩니다. 계정 ID **333333333333**에서 나온 로그 이벤트는 계정 **333333333333**의 소유자가 구독 필터를 생성하고 나면 그 즉시 대상으로 이동하기 시작합니다.

# 혼동된 대리자 방지
<a name="Subscriptions-confused-deputy"></a>

혼동된 대리자 문제는 작업을 수행할 권한이 없는 엔터티가 권한이 더 많은 엔터티에게 작업을 수행하도록 강요할 수 있는 보안 문제입니다. 에서 AWS교차 서비스 가장은 혼동된 대리자 문제를 초래할 수 있습니다. 교차 서비스 가장은 한 서비스(직접 호출하는 서비스)가 다른 서비스(직접 호출되는 서비스)를 직접 호출할 때 발생할 수 있습니다. 직접 호출하는 서비스는 다른 고객의 리소스에 대해 액세스 권한이 없는 방식으로 작동하게 권한을 사용하도록 조작될 수 있습니다. 이를 방지하기 위해는 계정의 리소스에 대한 액세스 권한이 부여된 서비스 보안 주체를 사용하여 모든 서비스에 대한 데이터를 보호하는 데 도움이 되는 도구를 AWS 제공합니다.

리소스 정책에서 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn), [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount), [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceorgid](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceorgid) 및 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceorgpaths](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceorgpaths) 글로벌 조건 컨텍스트 키를 사용하여 리소스에 다른 서비스를 제공하는 권한을 제한하는 것이 좋습니다. `aws:SourceArn`을 사용하면 하나의 리소스만 교차 서비스 액세스 권한과 연결됩니다. `aws:SourceAccount`를 사용하면 해당 계정의 모든 리소스가 교차 서비스 사용 권한과 연결됩니다. `aws:SourceOrgID`를 사용하면 조직 내 모든 계정의 모든 리소스가 교차 서비스 사용 권한과 연결될 수 있습니다. `aws:SourceOrgPaths`를 사용하면 AWS Organizations 경로 내 계정의 모든 리소스가 교차 서비스 사용 권한과 연결됩니다. 경로 사용 및 이해에 대한 자세한 내용은 [AWS Organizations 개체 경로 이해를](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_last-accessed-view-data-orgs.html#access_policies_last-accessed-viewing-orgs-entity-path) 참조하세요.

혼동된 대리인 문제로부터 보호하는 가장 효과적인 방법은 리소스의 전체 ARN이 포함된 `aws:SourceArn`글로벌 조건 컨텍스트 키를 사용하는 것입니다. 리소스의 전체 ARN을 모르거나 여러 리소스를 지정하는 경우, ARN의 알 수 없는 부분에 대해 와일드카드 문자(`*`)를 포함한 `aws:SourceArn` 글로벌 조건 컨텍스트 키를 사용합니다. 예: `arn:aws:servicename:*:123456789012:*` 

만약 `aws:SourceArn` 값에 Amazon S3 버킷 ARN과 같은 계정 ID가 포함되어 있지 않은 경우, 권한을 제한하려면 두 `aws:SourceAccount` 및 `aws:SourceArn`를 모두 사용해야 합니다.

혼동된 대리자 문제로부터 보호하려면 리소스 기반 정책에서 리소스의 조직 ID 또는 조직 경로와 함께 `aws:SourceOrgID` 또는 `aws:SourceOrgPaths` 글로벌 조건 컨텍스트 키를 사용합니다. `aws:SourceOrgID` 또는 `aws:SourceOrgPaths` 키가 포함된 정책에는 올바른 계정이 자동으로 포함되며 조직에서 계정을 추가, 제거 또는 이동할 때 정책을 수동으로 업데이트할 필요가 없습니다.

CloudWatch Logs에 대한 액세스 권한을 부여하여에서 Amazon Kinesis Data Streams 및 Firehose에 데이터를 쓰[1단계: 대상 생성](CreateDestination.md)고 `aws:SourceArn` 글로벌 조건 컨텍스트 키를 사용하여 혼동된 대리자 문제를 방지하는 방법을 [2단계: 대상 생성](CreateFirehoseStreamDestination.md) 보여주는 문서화된 정책입니다.

# 로그 재귀 방지
<a name="Subscriptions-recursion-prevention"></a>

구독 필터에는 방지하지 않을 경우 CloudWatch Logs와 대상 모두에서 수집 요금 청구를 크게 증가시킬 수 있는 로그 재귀를 초래할 위험이 있습니다. 이는 구독 전송 워크플로의 결과로 로그 이벤트를 수신하는 로그 그룹과 구독 필터가 연결될 때 발생할 수 있습니다. 로그 그룹에 수집된 로그는 대상으로 전달되어 로그 그룹이 더 많은 로그를 수집하게 되고, 이 로그는 대상으로 다시 전달되어 재귀 루프를 생성합니다.

예를 들어, 로그 이벤트를 Amazon S3로 전달하는 Firehose가 대상인 구독 필터를 생각해 보세요. 또한 Amazon S3에 전달되는 새 이벤트를 처리하고 일부 로그를 자체 생성하는 Lambda 함수도 있습니다. 구독 필터가 Lambda 함수의 로그 그룹에 적용되는 경우 함수가 생성한 로그 이벤트가 대상의 Firehose와 Amazon S3로 전달되고, 그러면 함수가 다시 간접 호출되어 더 많은 로그가 생성되고 Firehose와 Amazon S3로 전달되어 또 다른 함수 간접 호출을 초래하는 현상이 계속됩니다. 이 현상이 무한 루프로 발생하여 로그 수집, Firehose, Amazon S3에서 예상치 못한 요금 청구 증가로 이어집니다.

CloudWatch Logs에 대해 흐름 로그가 활성화된 VPC에 Lambda 함수가 연결된 경우 VPC의 로그 그룹도 로그 재귀를 일으킬 수 있습니다.

구독 전송 워크플로의 일부인 로그 그룹에는 구독 필터를 적용하지 않는 것이 좋습니다. 계정 수준 구독 필터의 경우 `PutAccountPolicy` API의 `selectionCriteria` 파라미터를 사용하여 정책에서 이러한 로그 그룹을 제외하세요.

로그 그룹을 제외할 때는 로그를 생성하고 구독 전송 워크플로의 일부일 수 있는 다음 AWS 서비스를 고려하십시오.
+ Amazon EC2와 Fargate
+ Lambda
+ AWS 단계 함수
+ CloudWatch Logs에 대해 활성화된 Amazon VPC 흐름 로그

**참고**  
Lambda 대상의 로그 그룹에서 생성된 로그 이벤트는 계정 수준 구독 필터 정책의 경우 Lambda 함수로 다시 전달되지 않습니다. 이 경우 계정 구독 정책에는 `selectionCriteria`를 사용하여 대상 Lambda 함수의 로그 그룹을 제외할 필요가 없습니다.