

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用订阅实时处理日志数据
<a name="Subscriptions"></a>

您可以使用订阅来访问来自 CloudWatch 日志的实时日志事件源，并将其传输到其他服务，例如 Amazon Kinesis 流、Amazon Data Firehose 流，或者 AWS Lambda 用于自定义处理、分析或加载到其他系统。当将录入事件发送到接收它们的服务时，它们会经过 base64 编码并使用 gzip 格式进行压缩。

您还可以使用 CloudWatch 日志集中化将来自多个账户和地区的日志数据复制到一个中心位置。有关更多信息，请参阅 [跨账户跨区域日志集中化](CloudWatchLogs_Centralization.md)。

要开始订阅日志事件，请创建接收资源，例如 Amazon Kinesis Data Streams 流，事件将在其中传送。订阅筛选器定义了筛选器模式，用于筛选哪些日志事件会传递到您的 AWS 资源，以及有关将匹配的日志事件发送到何处的信息。日志事件在摄取后不久（通常不到三分钟）就会发送到接收资源。

**注意**  
如果具有订阅的日志组使用日志转换，则会将筛选模式与日志事件的转换版本进行比较。有关更多信息，请参阅 [在摄取期间转换日志](CloudWatch-Logs-Transformation.md)。

您可以在账户级别和日志组级别创建订阅。每个账户对于每个区域可以有一个账户级订阅筛选条件。每个日志组最多只能有两个与其关联的订阅筛选条件。

**注意**  
如果目标服务返回可重试的错误，例如限制异常或可重试的服务异常（例如 HTTP 5xx），则 CloudWatch 日志会继续重试传送长达 24 小时。 CloudWatch 如果错误是不可重试的错误（例如或），则日志不会尝试重新传送。 AccessDeniedException ResourceNotFoundException在这些情况下，订阅筛选器最多会被禁用 10 分钟，然后 CloudWatch Logs 会重试向目标发送日志。在此禁用期间，将跳过日志。

CloudWatch 日志还会生成有关将日志事件转发给订阅的 CloudWatch 指标。有关更多信息，请参阅 [使用 CloudWatch 指标进行监控](CloudWatch-Logs-Monitoring-CloudWatch-Metrics.md)。

 您还可以使用 CloudWatch 日志订阅将日志数据近乎实时地流式传输到 Amazon S OpenSearch ervice 集群。有关更多信息，请参阅将[ CloudWatch 日志数据流式传输到 Amazon OpenSearch 服务](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_OpenSearch_Stream.html)。

仅标准日志类中的日志组支持订阅。有关日志类的更多信息，请参阅 [日志类](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 日志应如何解释每个日志事件中的数据的符号描述，以及限制传送到目标 AWS 资源的内容的筛选表达式。有关筛选条件模式语法的更多信息，请参阅 [指标筛选条件、订阅筛选条件、筛选日志事件和 Live Tail 的筛选条件模式语法](FilterAndPatternSyntax.md)。

**目标 ARN**  
您要用作订阅源目标的亚马逊 Kinesis Data Streams 流、Firehose 流或 Lambda 函数的亚马逊资源名称 (ARN)。

**角色 ARN**  
一个 IAM 角色，它向 CloudWatch Logs 授予将数据放入所选目标所需的权限。Lambda 目标不需要此角色，因为 CloudWatch 日志可以从 Lambda 函数本身的访问控制设置中获得必要的权限。

**分配**  
当目标是 Amazon Kinesis Data Streams 流中的流时，用于将日志数据分配到目标的方法。默认情况下，日志数据按日志流进行分组。为了实现更均匀的分配，您可以对日志数据进行随机分组。

对于日志组级别的订阅，还包括下面的关键元素：

**日志组名称**  
要将订阅筛选条件关联到的日志组。上传到此日志组的所有日志事件都受订阅筛选条件的约束，与该筛选条件匹配的日志事件将被传输到接收匹配日志事件的目标服务。

对于账户级别的订阅，还包括下面的关键元素：

**选择标准**  
用于选择哪些日志组应用了账户级别订阅筛选条件的标准。如果不指定此元素，则账户级别订阅筛选条件将应用于账户中的所有日志组。此字段用于防止无限日志循环。有关无限日志循环问题的更多信息，请参阅日志 [防止日志递归](Subscriptions-recursion-prevention.md)。  
选择标准的大小限制为 25 KB。

对于集中式日志组，还包括下面的关键元素。这些元素可用作字段选择标准，以帮助识别日志数据的来源，从而对从集中式日志派生的指标进行更精细的筛选和分析。

**@aws.account**  
此字段标识日志事件的起源 AWS 账户 ID。

**@aws.region**  
此字段标识生成日志事件的 AWS 区域。

# 日志组级别订阅筛选条件
<a name="SubscriptionFilters"></a>

 您可以将订阅筛选器与亚马逊 Kinesis Data Streams AWS Lambda、Amazon Data Firehose 或亚马逊服务一起使用。 OpenSearch 通过订阅筛选条件发送到服务的日志将经过 base64 编码并使用 gzip 格式进行压缩。如果您使用集中式日志 AWS Organizations，则可以选择发出`@aws.account`和`@aws.region`系统字段，以确定哪些数据来自组织中的哪些账户和区域。本节提供了一些示例，您可以按照这些示例创建将 CloudWatch 日志数据发送到 Firehose、Lambda、Amazon Kinesis Data Streams 和 Service 的日志订阅筛选器。 OpenSearch 

**注意**  
 如果要搜索日志数据，请参阅 [Filter and pattern syntax](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html)。

**Topics**
+ [示例 1：使用亚马逊 Kinesis Data Streams 的订阅筛选条件](#DestinationKinesisExample)
+ [示例 2：带有以下内容的订阅过滤器 AWS Lambda](#LambdaFunctionExample)
+ [示例 3：Amazon Data Firehose 订阅筛选条件](#FirehoseExample)
+ [示例 4：亚马逊 OpenSearch 服务的订阅筛选条件](#OpenSearchExample)

## 示例 1：使用亚马逊 Kinesis Data Streams 的订阅筛选条件
<a name="DestinationKinesisExample"></a>

以下示例将订阅筛选条件与包含 AWS CloudTrail 事件的日志组关联。订阅筛选器会将通过 “根” AWS 凭证记录的每项活动发送到 Amazon Kinesis Data Streams 中名为 RootAccess “” 的直播中。 有关如何向 CloudWatch 日志发送 AWS CloudTrail 事件的更多信息，请参阅*AWS CloudTrail 用户指南*中的[向 CloudWatch 日志发送 CloudTrail 事件](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cw_send_ct_events.html)。

**注意**  
在创建 流之前，请计算将生成日志数据的卷。请确保创建具有足够分片的 流来处理此卷。如果流没有足够的分片，日志流将受限制。有关流卷限制的更多信息，请参阅[限额和限制](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)或指定`random``distribution`何时创建订阅筛选器[ put-subscription-filter](https://awscli.amazonaws.com/v2/documentation/api/2.4.18/reference/logs/put-subscription-filter.html)。默认情况下，流筛选条件分配按日志流进行，这可能会导致节流。
使用 CloudWatch 指标监控您的直播。这可以帮助您识别任何节流并相应地调整配置。例如，该`DeliveryThrottling`指标可用于跟踪在将数据转发到订阅目标时限制 CloudWatch 日志的日志事件的数量。有关监控的更多信息，请参阅[使用 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 订阅筛选模式，使其与 Amazon Kinesis Data Streams 中的直播容量相匹配。如果您向流发送的数据过多，则可能需要减小筛选器大小或调整筛选条件。

**为 Amazon Kinesis Data Streams 创建订阅筛选条件**

1. 使用以下命令创建目标 流：

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

1. 请耐心等待，直到 流变为活动状态（这可能需要一两分钟）。**你可以使用以下 Amazon Kinesis Data [St](https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html) reams describe-stream 命令来检查。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. 创建 IAM 角色，该角色将授予 CloudWatch 日志将数据放入您的直播的权限。首先，您需要在文件（例如 `~/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 日志可以对您的账户执行的操作。首先，您将在文件（例如 `~/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. 在直播处于 “活动” **状态**且您已创建 IAM 角色后，您可以创建 CloudWatch 日志订阅筛选器。订阅筛选条件将立即让实时日志数据开始从所选日志组流动到您的 流：

   ```
   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. 设置订阅过滤器后，Lo CloudWatch gs 会将所有与过滤器模式匹配的传入日志事件转发到您的直播中。你可以通过获取 Amazon Kinesis Data Streams 分片迭代器并使用 Amazon Kinesis Data Streams 获取记录命令来获取一些 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 记录中的**数据**属性采用 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": [
           "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 日志可能会发出 “CONTROL\$1MESSAGE” 类型的 Amazon Kinesis Data Streams 记录，主要用于检查目标是否可达。  
**logEvents**  
表示为一组日志事件记录的实际日志数据。“id”属性是每个日志事件的唯一标识符。

## 示例 2：带有以下内容的订阅过滤器 AWS Lambda
<a name="LambdaFunctionExample"></a>

在此示例中，您将创建一个 Lo CloudWatch gs 订阅过滤器，用于将日志数据发送到您的 AWS Lambda 函数。

**注意**  
在创建 Lambda 函数之前，请计算将生成的日志数据量。请确保创建一个处理此卷的函数。如果函数没有足够的卷，日志流将受限制。有关 Lambda 限制的更多信息，请参阅 [AWS Lambda 限制](https://docs.aws.amazon.com/lambda/latest/dg/limits.html)。

**为 Lambda 创建订阅筛选条件**

1. 创建 AWS Lambda 函数。

   确保您已设置 Lambda 执行角色。有关更多信息，请参阅 *AWS Lambda 开发人员指南*中的[步骤 2.2：创建 IAM 角色（执行角色）](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 函数的输出，请导航到 Lambda 函数，您将在其中看到/中的输出：aws/lambda/helloworld

   ```
   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 日志可能会发出 “CONTROL\$1MESSAGE” 类型的 Lambda 记录，主要用于检查目标是否可达。  
**logEvents**  
表示为一组日志事件记录的实际日志数据。“id”属性是每个日志事件的唯一标识符。

## 示例 3：Amazon Data Firehose 订阅筛选条件
<a name="FirehoseExample"></a>

在此示例中，您将创建一个 CloudWatch 日志订阅，该订阅将与您定义的筛选条件匹配的所有传入日志事件发送到您的 Amazon Data Firehose 传输流。从 CloudWatch Logs 发送到 Amazon Data Firehose 的数据已使用 gzip 第 6 级压缩进行压缩，因此您无需在 Firehose 传输流中使用压缩。然后，可以使用 Firehose 中的解压缩功能自动解压缩日志。如需了解更多信息，请参阅[向 Firehose 发送 CloudWatch 日志](https://docs.aws.amazon.com/logs/SubscriptionFilters.html#FirehoseExample)。

**注意**  
在创建 Firehose 流之前，请计算将生成的日志数据量。请确保创建一个处理此数据量的 Firehose 流。如果流无法处理卷，则日志流将受限制。有关 Firehose 流数据量限制的更多信息，请参阅 [Amazon Data Firehose Data Limits](https://docs.aws.amazon.com/firehose/latest/dev/limits.html)。

**为 Firehose 创建订阅筛选条件**

1. 创建 Amazon Simple Storage Service（Amazon S3）存储桶。我们建议您使用专为 Logs 创建的存储 CloudWatch 桶。但是，如果要使用现有存储桶，请跳至第 2 步。

   运行以下命令，将占位符区域替换为您想使用的区域：

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

   下面是示例输出：

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

1. 创建 IAM 角色，该角色将授予 Amazon Data Firehose 将数据放入您的 Amazon S3 存储桶的权限。

   有关更多信息，请参阅《*Amazon Data Firehose 开发人员指南*》中的 [Controlling Access with 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 的占位符值替换为您创建的角色和****存储**分区： ARNs 

   ```
   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"}'
   ```

   请注意，对于已交付的 Amazon S3 对象，Firehose 会自动使用YYYY/MM/DD/HH世界标准时间格式的前缀。您可以指定要添加在该时间格式前缀前面的额外前缀。如果前缀以正斜杠（/）结束，则在 Amazon S3 存储桶中显示为文件夹。

1. 请耐心等待，直到流变为活动状态（这可能需要几分钟时间）。**你可以使用 Fire **describe-delivery-stream**hose 命令来检查。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. 创建 IAM 角色，该角色向 CloudWatch 日志授予将数据放入 Firehose 传输流的权限。首先，使用文本编辑器在文件 `~/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 日志可以对您的账户执行的操作。首先，使用文本编辑器创建权限策略文件（例如 `~/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 日志订阅筛选条件。订阅筛选条件将立即启动从所选日志组到您的 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. 设置订阅筛选器后，Lo CloudWatch gs 会将所有与筛选模式匹配的传入日志事件转发到您的 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：亚马逊 OpenSearch 服务的订阅筛选条件
<a name="OpenSearchExample"></a>

在此示例中，您将创建一个 CloudWatch 日志订阅，该订阅将与您定义的过滤器匹配的传入日志事件发送到您的 OpenSearch 服务域。

**为 OpenSearch 服务创建订阅筛选器**

1. 创建 OpenSearch 服务域。有关更多信息，请参阅[创建 OpenSearch 服务域](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/createupdatedomains.html#createdomains)

1. 打开 CloudWatch 控制台，网址为[https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)。

1.  在导航窗格中，选择**日志组**。

1. 选择日志组的名称。

1. 选择**操作**、**订阅筛选条件**、**创建亚马逊 OpenSearch 服务订阅筛选条件**。

1. 选择是要流式传输到此账户还是其他账户中的集群。
   + 如果选择**此账户**，请选择您在步骤 1 中创建的域。
   + 如果选择**其他账户**，请输入该域的 ARN 和端点。

1.  如果您选择了其他账户，请提供域 ARN 和端点。

1. 对于 Amazon S OpenSearch ervice 集群，请选择将要传送日志组数据的集群的名称

1. 选择一种日志格式。

1. 对于**订阅筛选条件模式**，输入要在您的日志事件中查找的字词或模式。这样可以确保您仅将感兴趣的数据发送到您的 OpenSearch 服务集群。有关更多信息，请参阅 [指标筛选条件的筛选条件模式语法](FilterAndPatternSyntaxForMetricFilters.md)。

1. （可选）对于 **Select log data to test（选择要测试的日志数据）**，请选择一个日志流，然后选择 **Test pattern（测试模式）**，以确认搜索筛选器是否会返回您期望的结果。

1. 选择 **Start streaming（开始流式传输）**。

# 账户级订阅筛选条件
<a name="SubscriptionFilters-AccountLevel"></a>

**重要**  
订阅筛选条件可能会出现无限递归循环的风险，如果不加以解决，可能会导致提取计费大幅增加。为了降低这种风险，我们建议您在账户级订阅筛选条件中使用选择标准来排除从属于订阅交付工作流一部分的资源中提取日志数据的日志组。有关此问题以及确定要排除哪些日志组的更多信息，请参阅 [防止日志递归](Subscriptions-recursion-prevention.md)。

 您可以设置一个账户级别的订阅策略，其包括账户中的一部分日志组。账户订阅政策可以与亚马逊 Kinesis Data St AWS Lambda reams 或 Amazon Data Firehose 配合使用。通过账户级订阅策略发送到服务的日志采用 base64 编码并使用 gzip 格式进行压缩。本节提供了一些示例，您可以按照这些示例为亚马逊 Kinesis Data Streams、Lambda 和 Firehose 创建账户级订阅。

**注意**  
要查看您账户中所有订阅筛选策略的列表，请使用 `describe-account-policies` 命令并将 `--policy-type` 参数的值设置为 `SUBSCRIPTION_FILTER_POLICY`。有关更多信息，请参阅 [ describe-account-policies¶](https://docs.aws.amazon.com/cli/latest/reference/logs/describe-account-policies.html)。

**Topics**
+ [示例 1：使用亚马逊 Kinesis Data Streams 的订阅筛选条件](#DestinationKinesisExample-AccountLevel)
+ [示例 2：带有以下内容的订阅过滤器 AWS Lambda](#LambdaFunctionExample-AccountLevel)
+ [示例 3：Amazon Data Firehose 订阅筛选条件](#FirehoseExample-AccountLevel)

## 示例 1：使用亚马逊 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 小时后，失败的交付项将被丢弃。  
要减轻节流的风险，您可以执行以下步骤：  
使用指标监控您的 Amazon Kinesis Data Streams CloudWatch 流。这可以帮助您识别节流并相应地调整配置。例如，该`DeliveryThrottling`指标跟踪在将数据转发到订阅目标时限制 CloudWatch 日志的日志事件的数量。有关更多信息，请参阅 [使用 CloudWatch 指标进行监控](CloudWatch-Logs-Monitoring-CloudWatch-Metrics.md)。
在 Amazon Kinesis Data Streams 中对直播使用按需容量模式。按需模式会随着工作负载的增加或减少立即进行调整。有关更多信息，请参阅 [On-demand mode](https://docs.aws.amazon.com/streams/latest/dev/how-do-i-size-a-stream.html#ondemandmode)。
限制您的 CloudWatch 日志订阅筛选模式，使其与 Amazon Kinesis Data Streams 中的直播容量相匹配。如果您向流发送的数据过多，则可能需要减小筛选器大小或调整筛选条件。

以下示例使用账户级订阅策略将所有日志事件转发到 Amazon Kinesis Data Streams 中的数据流。筛选模式会将任何日志事件与文本进行匹配，`Test`并将其转发到 Amazon Kinesis Data Streams 中的数据流。

**为亚马逊 Kinesis Data Streams 创建账户级订阅政策**

1. 使用以下命令创建目标 流：

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

1. 等待几分钟让流变为活动状态。**您可以使用 desc [ribe-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. 创建 IAM 角色，该角色将授予 CloudWatch 日志将数据放入您的直播的权限。首先，您需要在文件（例如 `~/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 日志可以对您的账户执行的操作。首先，您将在文件（例如 `~/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. 在直播处于 A **ctiv** e 状态且您已创建 IAM 角色后，您可以创建 CloudWatch 日志订阅筛选器策略。该策略会立即启动实时日志数据流。在此示例中，所有包含字符串 `ERROR` 的日志事件都将流式传输，但名为 `LogGroupToExclude1` 和 `LogGroupToExclude2` 的日志组中的日志事件除外。

   ```
   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. 设置订阅过滤器后，Lo CloudWatch gs 会将所有符合过滤模式和选择标准的传入日志事件转发到您的直播中。

   `selection-criteria` 字段是可选的，但对于从订阅筛选条件中排除可能导致无限日志递归的日志组非常重要。有关此问题以及确定要排除哪些日志组的更多信息，请参阅 [防止日志递归](Subscriptions-recursion-prevention.md)。目前，NOT IN 是 `selection-criteria` 唯一支持的运算符。

   您可以使用 Amazon Kinesis Data Streams 分片迭代器并使用 Amazon Kinesis Data Streams 命令获取一些 Amazon Kinesis `get-records` 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 记录中的**数据**属性采用 gzip 格式进行 base64 编码和压缩。您可使用以下 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 日志可能会发出 “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>

在此示例中，您将创建一个 CloudWatch 日志账户级别的订阅筛选器策略，该策略将日志数据发送到您的 AWS Lambda 函数。

**警告**  
在创建 Lambda 函数之前，请计算将生成的日志数据量。请确保创建一个处理此卷的函数。如果该函数无法处理该量，则日志流将受限制。由于所有日志组或账户的部分日志组的日志事件都被转发到目标，因此存在节流风险。有关 Lambda 限制的更多信息，请参阅 [AWS Lambda 限制](https://docs.aws.amazon.com/lambda/latest/dg/limits.html)。

**为 Lambda 创建账户级订阅筛选策略**

1. 创建 AWS Lambda 函数。

   确保您已设置 Lambda 执行角色。有关更多信息，请参阅 *AWS Lambda 开发人员指南*中的[步骤 2.2：创建 IAM 角色（执行角色）](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. 使用以下命令创建账户级订阅筛选策略，将占位符账户替换为您自己的账户。在此示例中，所有包含字符串 `ERROR` 的日志事件都将流式传输，但名为 `LogGroupToExclude1` 和 `LogGroupToExclude2` 的日志组中的日志事件除外。

   ```
   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"
   ```

   设置订阅过滤器后，Lo CloudWatch gs 会将所有符合过滤模式和选择标准的传入日志事件转发到您的直播中。

   `selection-criteria` 字段是可选的，但对于从订阅筛选条件中排除可能导致无限日志递归的日志组非常重要。有关此问题以及确定要排除哪些日志组的更多信息，请参阅 [防止日志递归](Subscriptions-recursion-prevention.md)。目前，NOT IN 是 `selection-criteria` 唯一支持的运算符。

1. （可选）使用样本日志事件进行测试。在出现命令提示符时，运行以下命令，以将一条简单的日志消息放入已订阅的流中。

   要查看 Lambda 函数的输出，请导航到 Lambda 函数，您将在其中看到/中的输出：aws/lambda/helloworld

   ```
   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 日志可能会发出 “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>

在此示例中，您将创建 CloudWatch 日志账户级别的订阅筛选器策略，该策略将与您定义的筛选条件匹配的传入日志事件发送到您的 Amazon Data Firehose 传输流。从 CloudWatch Logs 发送到 Amazon Data Firehose 的数据已使用 gzip 第 6 级压缩进行压缩，因此您无需在 Firehose 传输流中使用压缩。然后，可以使用 Firehose 中的解压缩功能自动解压缩日志。有关更多信息，请参阅使用日志[写入 Kinesis Data CloudWatch Fire](https://docs.aws.amazon.com/firehose/latest/dev/writing-with-cloudwatch-logs.html) hose。

**警告**  
在创建 Firehose 流之前，请计算将生成的日志数据量。请确保创建一个处理此数据量的 Firehose 流。如果流无法处理卷，则日志流将受限制。有关 Firehose 流数据量限制的更多信息，请参阅 [Amazon Data Firehose Data Limits](https://docs.aws.amazon.com/firehose/latest/dev/limits.html)。

**为 Firehose 创建订阅筛选条件**

1. 创建 Amazon Simple Storage Service（Amazon S3）存储桶。我们建议您使用专为 Logs 创建的存储 CloudWatch 桶。但是，如果要使用现有存储桶，请跳至第 2 步。

   运行以下命令，将占位符区域替换为您想使用的区域：

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

   下面是示例输出：

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

1. 创建 IAM 角色，该角色将授予 Amazon Data Firehose 将数据放入您的 Amazon S3 存储桶的权限。

   有关更多信息，请参阅《*Amazon Data Firehose 开发人员指南*》中的 [Controlling Access with 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 的占位符值替换为您创建的角色和****存储**分区： ARNs 

   ```
   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"}'
   ```

   NFirehose 对于已交付的 Amazon S3 对象，自动使用 YYYY/MM/DD/HH UTC 时间格式的前缀。您可以指定要添加在该时间格式前缀前面的额外前缀。如果前缀以正斜杠（/）结束，则在 Amazon S3 存储桶中显示为文件夹。

1. 等待几分钟让流变为活动状态。**你可以使用 Fire **describe-delivery-stream**hose 命令来检查。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. 创建 IAM 角色，该角色向 CloudWatch 日志授予将数据放入 Firehose 传输流的权限。首先，使用文本编辑器在文件 `~/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 日志可以对您的账户执行的操作。首先，使用文本编辑器创建权限策略文件（例如 `~/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 日志账户级别的订阅筛选器策略。该策略将立即启动从所选日志组到您的 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. 设置订阅筛选器后，Lo CloudWatch gs 会将与筛选模式匹配的传入日志事件转发到您的 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 账户的所有者协作，并在您的 AWS 资源上接收他们的日志事件，例如 Amazon Kinesis 或 Amazon Data Firehose 流（这称为跨账户数据共享）。例如，可以从集中式的 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>

创建跨账户订阅时，可以指定单个账户或企业作为发件人。如果指定企业，则此过程允许企业中的所有账户向接收方账户发送日志。

要跨账户共享日志数据，您需要建立日志数据发送者和接收者：
+ **日志数据发送者**-从收件人那里获取目标信息，并让 Lo CloudWatch gs 知道它已准备好将其日志事件发送到指定目标。在本节其余部分的步骤中，显示日志数据发送者的虚构 AWS 账号为 111111111111。

  如果您将在企业中设立多个账户向收件人账户发送日志，则可以创建策略，授予企业中的所有账户向收件人账户发送日志的权限。您仍然必须为每个发件人账户设置单独的订阅筛选条件。
+ **日志数据接收者**-设置封装 Amazon Kinesis Data Streams 流的目标，并 CloudWatch 让日志知道接收者想要接收日志数据。接收者随后与发送者共享与此目标有关的信息。在本节其余部分的步骤中，显示日志数据接收者的虚构 AWS 账号为 999999999999。

要开始接收来自跨账户用户的日志事件，日志数据接收者首先创建 CloudWatch 日志目标。每个目标都包含以下键元素：

**目标名称**  
您要创建的目标的名称。

**目标 ARN**  
您要用作订阅 Feed 目标的 AWS 资源的亚马逊资源名称 (ARN)。

**角色 ARN**  
一个 AWS Identity and Access Management (IAM) 角色，它向 CloudWatch Logs 授予将数据放入所选数据流的必要权限。

**访问策略**  
一个 IAM policy 文档（采用 JSON 格式，使用 IAM policy 语法编写），用于管理有权对您的目标进行写入的用户组。

**注意**  
日志组和目标必须位于同一 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：跨账户目标的 Add/validate 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 允许日志向其写入数据的角色。

创建目标后， CloudWatch Logs 会代表收件人账户向目标发送一条测试消息。当订阅筛选器稍后处于活动状态时，Logs 会代表源账户将 CloudWatch 日志事件发送到目标。

**创建目标**

1. 在收款人账户中，在 Amazon Kinesis Data Streams 中创建目标流。在命令提示符下，输入：

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

1. 等到 流变为活动状态。**你可以使用 a **ws kinesis describe-stream** 命令来检查。StreamDescription StreamStatus**财产。此外，请记下 **StreamDescription.streamArn** 的值，因为您稍后会将其传递给 Logs： CloudWatch 

   ```
   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. 创建 IAM 角色以授予 CloudWatch Logs 将数据放入您的直播的权限。首先，你需要在文件 **\$1/ TrustPolicyFor cwl** .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 角色，并指定信任策略文件。请记下返回的 Role.Arn 值，因为它稍后也会传递给 CloudWatch Logs：

   ```
   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 日志可以对您的账户执行哪些操作。首先，使用文本编辑器在文件 **\$1/ PermissionsFor cwl** .json 中创建权限策略：

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

1. 使用 a **w** s 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 日志目标。

   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** action，并向发件人账户授予访问目标的权限。

      该策略向发送日志的 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
      ```

      此访问策略允许 AWS 账户中编号为 111111111111 的用户使用 ARN arn: aws: logs:: 999999999999: destination: testDestination: testDest **PutSubscriptionFilter**ination呼叫目的地。*region*任何其他用户试图拨 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)。

本节中的步骤创建一个 IAM 角色，该角色 CloudWatch 可以假设和验证发件人账户是否有权针对收件人目的地创建订阅筛选条件。

在发送者账户中执行本节中的步骤。该角色必须存在于发送者账户中，并且您在订阅筛选器中指定该角色的 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：跨账户目标的 Add/validate 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. 输入以下命令以检查使用哪个 IAM 角色或 IAM 用户来运行 AWS 日志命令。

   ```
   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. 登录发送账户并使用您在步骤 1 AWS 管理控制台 中输入的命令的输出中返回的 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 日志发送 CloudTrail 事件](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html)中的说明进行操作，并创建了一个包含您的 CloudTrail 事件的日志组。这些步骤假定此日志组的名称为 `CloudTrail/logs`。

输入以下命令时，请务必以 IAM 用户身份登录，或者使用在 [步骤 3：跨账户目标的 Add/validate IAM 权限](Subscription-Filter-CrossAccount-Permissions.md) 中为其添加策略的 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 区域。但是，目标可以指向位于不同区域的 AWS 资源，例如 Amazon Kinesis Data Streams 流。

# 验证日志事件流
<a name="ValidateLogEventFlow"></a>

创建订阅过滤器后，Lo CloudWatch gs 会将所有与过滤器模式匹配的传入日志事件转发到封装在名为 “” 的目标流中的流。**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 日志可能会发出 “CONTROL\$1MESSAGE” 类型的 Amazon Kinesis Data Streams 记录，主要用于检查目标是否可达。

**logEvents**  
表示为一组日志事件记录的实际日志数据。ID 属性是每个日志事件的唯一标识符。

# 在运行时修改目标成员资格
<a name="ModifyDestinationMembership"></a>

您可能遇到必须在您拥有的目标中添加或删除某些用户的成员资格的情况。您可通过新访问策略对您的目标使用 `put-destination-policy` 命令。在以下示例中，将阻止之前添加的账户 **111111111111** 再发送任何日志数据，并将启用账户 **222222222222**。

1. 获取当前与目标 **TestDest** ination 关联的策略并记下：**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** 中的日志事件。在账户 **222222222222** 的所有者创建订阅筛选条件后，账户 ID **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 角色，该角色 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"
```

**更新订阅筛选器以开始使用组织来 IDs 获得跨账户日志权限**

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. 输入以下命令，将刚创建的策略附加到现有目标。要更新目标以使用带有组织 ID 的访问策略，而不是列出特定 AWS 账户的访问策略 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>

要跨账户共享日志数据，您需要建立日志数据发送者和接收者：
+ **日志数据发送者**-从收件人那里获取目标信息，并让 Lo CloudWatch gs 知道它已准备好将其日志事件发送到指定目标。在本节其余部分的步骤中，显示日志数据发送者的虚构 AWS 账号为 111111111111。
+ **日志数据接收者**-设置封装 Amazon Kinesis Data Streams 流的目标，并 CloudWatch 让日志知道接收者想要接收日志数据。接收者随后与发送者共享与此目标有关的信息。在本节其余部分的步骤中，显示日志数据接收者的虚构 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：跨账户目标的 Add/validate 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 开发人员指南*》中的 [Controlling Access](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. 创建 IAM 角色，授予 Firehose 将数据放入存储桶的权限。

   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 传输流。*amzn-s3-demo-bucket2-arn*使用正确的部署值替换*my-role-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 会代表收件人账户向目标发送一条测试消息。当订阅筛选器稍后处于活动状态时，Logs 会代表源账户将 CloudWatch 日志事件发送到目标。

**创建目标**

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. 当传输流处于活动状态时，创建 IAM 角色将授予 CloudWatch Logs 将数据放入您的 Firehose 流的权限。首先，你需要在文件 **\$1/ TrustPolicyFor cwl** .json 中创建信任策略。使用文本编辑器创建此策略。有关 CloudWatch 日志终端节点的更多信息，请参阅 [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 日志可以对您的账户执行哪些操作。首先，使用文本编辑器在文件 **\$1/ PermissionsFor cwl** .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 日志目标。

   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：跨账户目标的 Add/validate 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. 输入以下命令以检查使用哪个 IAM 角色或 IAM 用户来运行 AWS 日志命令。

   ```
   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. 登录发送账户并使用您在步骤 1 AWS 管理控制台 中输入的命令的输出中返回的 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 日志发送 AWS CloudTrail 事件的更多信息，请参阅*AWS CloudTrail 用户指南*中的[向 CloudWatch 日志发送 CloudTrail 事件](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html)。

输入以下命令时，请务必以 IAM 用户身份登录，或者使用在 [步骤 3：跨账户目标的 Add/validate IAM 权限](Subscription-Filter-CrossAccount-Permissions-Firehose.md) 中为其添加策略的 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 区域。但是，目标可以指向位于不同区域的 AWS 资源，例如Firehose流。

# 验证录入事件流
<a name="ValidateLogEventFlowFirehose"></a>

创建订阅过滤器后，Lo CloudWatch gs 会将所有与过滤器模式匹配的传入日志事件转发到 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. 获取当前与目标 **TestDest** ination 关联的策略并记下：**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** 中的日志事件。在账户 **333333333333** 的所有者创建订阅筛选条件后，账户 ID **333333333333** 中的日志事件就会立即开始流向目标。

# 使用 Amazon Kinesis Data Streams 的跨账户跨区域账户级别订阅
<a name="CrossAccountSubscriptions-Kinesis-Account"></a>

创建跨账户订阅时，可以指定单个账户或企业作为发件人。如果指定企业，则此过程允许企业中的所有账户向接收方账户发送日志。

要跨账户共享日志数据，您需要建立日志数据发送者和接收者：
+ **日志数据发送者**-从收件人那里获取目标信息，并让 Lo CloudWatch gs 知道它已准备好将其日志事件发送到指定目标。在本节其余部分的步骤中，显示日志数据发送者的虚构 AWS 账号为 111111111111。

  如果您将在企业中设立多个账户向收件人账户发送日志，则可以创建策略，授予企业中的所有账户向收件人账户发送日志的权限。您仍然必须为每个发件人账户设置单独的订阅筛选条件。
+ **日志数据接收者**-设置封装 Amazon Kinesis Data Streams 流的目标，并 CloudWatch 让日志知道接收者想要接收日志数据。接收者随后与发送者共享与此目标有关的信息。在本节其余部分的步骤中，显示日志数据接收者的虚构 AWS 账号为 999999999999。

要开始接收来自跨账户用户的日志事件，日志数据接收者首先创建 CloudWatch 日志目标。每个目标都包含以下键元素：

**目标名称**  
您要创建的目标的名称。

**目标 ARN**  
您要用作订阅 Feed 目标的 AWS 资源的亚马逊资源名称 (ARN)。

**角色 ARN**  
一个 AWS Identity and Access Management (IAM) 角色，它向 CloudWatch Logs 授予将数据放入所选数据流的必要权限。

**访问策略**  
一个 IAM policy 文档（采用 JSON 格式，使用 IAM policy 语法编写），用于管理有权对您的目标进行写入的用户组。

**注意**  
日志组和目标必须位于同一 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 允许日志向其写入数据的角色。

创建目标后， CloudWatch Logs 会代表收件人账户向目标发送一条测试消息。当订阅筛选器稍后处于活动状态时，Logs 会代表源账户将 CloudWatch 日志事件发送到目标。

**创建目标**

1. 在收款人账户中，在 Amazon Kinesis Data Streams 中创建目标流。在命令提示符下，输入：

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

1. 等到 流变为活动状态。**你可以使用 a **ws kinesis describe-stream** 命令来检查。StreamDescription StreamStatus**财产。此外，请记下 **StreamDescription.streamArn** 的值，因为您稍后会将其传递给 Logs： CloudWatch 

   ```
   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. 创建 IAM 角色以授予 CloudWatch Logs 将数据放入您的直播的权限。首先，你需要在文件 **\$1/ TrustPolicyFor cwl** .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 角色，并指定信任策略文件。请记下返回的 Role.Arn 值，因为它稍后也会传递给 CloudWatch Logs：

   ```
   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 日志可以对您的账户执行哪些操作。首先，使用文本编辑器在文件 **\$1/ PermissionsFor cwl** .json 中创建权限策略：

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

1. 使用 a **w** s 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 日志目标。

   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** action，并向发件人账户授予访问目标的权限。

      该策略向发送日志的 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
      ```

      此访问策略允许 AWS 账户中编号为 111111111111 的用户使用 ARN arn: aws: logs:: 999999999999: destination: testDestination: testDest **PutSubscriptionFilter**ination呼叫目的地。*region*任何其他用户试图拨 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)。

本节中的步骤创建一个 IAM 角色，该角色 CloudWatch 可以假设和验证发件人账户是否有权针对收件人目的地创建订阅筛选条件。

在发送者账户中执行本节中的步骤。该角色必须存在于发送者账户中，并且您在订阅筛选器中指定该角色的 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 区域内。但是，目标可以指向位于不同区域的 AWS 资源，例如 Amazon Kinesis Data Streams 流。

# 验证日志事件流
<a name="ValidateLogEventFlow-Account"></a>

创建账户级订阅筛选策略后，Lo CloudWatch gs 会将所有符合过滤模式和选择标准的传入日志事件转发到封装在名为 “” 的目标流中的流。**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 日志可能会发出 “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. 获取当前与目标 **TestDest** ination 关联的策略并记下：**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** 中的日志事件。在账户 **222222222222** 的所有者创建订阅筛选条件后，账户 ID **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 角色，该角色 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"
```

**更新订阅筛选器以开始使用组织来 IDs 获得跨账户日志权限**

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. 输入以下命令，将刚创建的策略附加到现有目标。要更新目标以使用带有组织 ID 的访问策略，而不是列出特定 AWS 账户的访问策略 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>

要跨账户共享日志数据，您需要建立日志数据发送者和接收者：
+ **日志数据发送者**-从收件人那里获取目标信息，并让 Lo CloudWatch gs 知道它已准备好将其日志事件发送到指定目标。在本节其余部分的步骤中，显示日志数据发送者的虚构 AWS 账号为 111111111111。
+ **日志数据接收者**-设置封装 Amazon Kinesis Data Streams 流的目标，并 CloudWatch 让日志知道接收者想要接收日志数据。接收者随后与发送者共享与此目标有关的信息。在本节其余部分的步骤中，显示日志数据接收者的虚构 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 开发人员指南*》中的 [Controlling Access](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. 创建 IAM 角色，授予 Firehose 将数据放入存储桶的权限。

   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 传输流。*amzn-s3-demo-bucket2-arn*使用正确的部署值替换*my-role-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 会代表收件人账户向目标发送一条测试消息。当订阅筛选器稍后处于活动状态时，Logs 会代表源账户将 CloudWatch 日志事件发送到目标。

**创建目标**

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. 当传输流处于活动状态时，创建 IAM 角色将授予 CloudWatch Logs 将数据放入您的 Firehose 流的权限。首先，你需要在文件 **\$1/ TrustPolicyFor cwl** .json 中创建信任策略。使用文本编辑器创建此策略。有关 CloudWatch 日志终端节点的更多信息，请参阅 [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 日志可以对您的账户执行哪些操作。首先，使用文本编辑器在文件 **\$1/ PermissionsFor cwl** .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 日志目标。

   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 区域内。但是，目标可以指向位于不同区域的 AWS 资源，例如Firehose流。

# 验证录入事件流
<a name="ValidateLogEventFlowFirehose-Account"></a>

创建订阅过滤器后，Lo CloudWatch gs 会将所有符合筛选模式和选择标准的传入日志事件转发到 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. 获取当前与目标 **TestDest** ination 关联的策略并记下：**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** 中的日志事件。在账户 **333333333333** 的所有者创建订阅筛选条件后，账户 ID **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)。

防范混淆代理问题最有效的方法是使用 `aws:SourceArn` 全局条件上下文键和资源的完整 ARN。如果不知道资源的完整 ARN，或者正在指定多个资源，请针对 ARN 未知部分使用带有通配符字符（`*`）的 `aws:SourceArn` 全局上下文条件键。例如 `arn:aws:servicename:*:123456789012:*`。

如果 `aws:SourceArn` 值不包含账户 ID，例如 Amazon S3 桶 ARN，您必须使用 `aws:SourceAccount` 和 `aws:SourceArn` 来限制权限。

要防范大规模混淆代理问题，请在基于资源的策略中将 `aws:SourceOrgID` 或 `aws:SourceOrgPaths` 全局条件上下文键与资源的组织 ID 或组织路径一起使用。包含 `aws:SourceOrgID` 或 `aws:SourceOrgPaths` 键的策略将自动包含正确的账户，并且当您在组织中添加、删除或移动账户时，无需手动更新策略。

记录的策略用于授予访问 CloudWatch 日志的权限，以便将数据写入 Amazon Kinesis Data Streams 和 Firehose[步骤 1：创建目标](CreateDestination.md)，[步骤 2：创建目标](CreateFirehoseStreamDestination.md)并显示如何使用`aws:SourceArn`全局条件上下文密钥来帮助防止混乱的副手问题。

# 防止日志递归
<a name="Subscriptions-recursion-prevention"></a>

订阅过滤器存在导致无限日志递归的风险，如果不加以防止，则可能导致 CloudWatch 日志和目标中的摄取账单大幅增加。当订阅筛选条件与由于订阅传输工作流而接收日志事件的日志组关联时，会发生这种情况。提取到日志组中的日志将传输到目标位置，从而导致日志组提取更多日志，然后这些日志将再次转发到目标位置，从而形成递归循环。

例如，考虑一个目标位置为 Firehose 的订阅筛选条件，它将日志事件传输到 Amazon S3。此外，还有一个 Lambda 函数，可以处理传输到 Amazon S3 的新事件并自行生成一些日志。如果将订阅筛选条件应用于 Lambda 函数的日志组，则该函数生成的日志事件将转发到目标位置的 Firehose 和 Amazon S3，然后它们将再次调用该函数，从而生成更多日志并将其转发到 Firehose 和 Amazon S3，导致再次调用该函数等。这将陷入无限循环，导致日志提取、Firehose 和 Amazon S3 的计费意外增加。

如果 Lambda 函数附加到为 CloudWatch 日志启用了流日志的 VPC，则该 VPC 的日志组也可能导致日志递归。

我们建议您不要将订阅筛选条件应用于属于订阅传输工作流一部分的日志组。对于账户级订阅筛选条件，请使用 `PutAccountPolicy` API 中的 `selectionCriteria` 参数从策略中排除这些日志组。

排除日志组时，请考虑以下生成日志的 AWS 服务，这些服务可能是您的订阅交付工作流程的一部分：
+ 带有 Fargate 的 Amazon EC2
+ Lambda
+ AWS Step Function
+ 为日志启用的 Amazon VPC 流 CloudWatch 日志

**注意**  
Lambda 目标的日志组生成的日志事件将不会被转发回账户级订阅筛选策略的 Lambda 函数。在这种情况下，账户订阅策略不需要使用 `selectionCriteria` 排除目标 Lambda 函数的日志组。