亚马逊AWS官方博客

如何为 Amazon Kinesis Data Streams 启用跨账户访问

当今的企业面临着大量实时数据,他们需要处理和分析这些数据以生成洞察。实时数据和洞察的即时交付使企业能够快速对来自设备的传感器数据、点击事件、用户参与以及基础设施事件等进行决策。

Amazon Kinesis Data Streams 提供了一个托管服务,让客户可以专注于构建和扩展流式应用程序,进行准实时数据处理,而无需管理基础设施。客户可以编写 Kinesis Data Streams 消费者应用程序,从 Kinesis Data Streams 读取数据并根据自己的需求进行处理。

通常情况下,Kinesis Data Streams 和消费者应用程序会位于同一个 AWS 账户中。然而,有些情况下客户可能采用多账户方法,导致 Kinesis Data Streams 和消费者应用程序运行在不同的账户中。使用多账户方法的主要原因包括:

  • 将 AWS 账户分配给不同的团队、项目或产品,以便实现快速创新,同时仍满足独特的安全需求。
  • 通过将 AWS 成本映射到特定的产品或服务线,简化 AWS 计费过程。
  • 为特定的安全性或合规性要求隔离账户。
  • 扩展资源并减轻受限于单个账户的 AWS 服务硬性限制。

以下选项可让您跨账户访问 Kinesis Data Streams:

  • Amazon Kinesis 客户端库(KCL)for Java 或使用 KCL 的 MultiLang Daemon。
  • Amazon Kinesis Data Analytics for Apache Flink – 支持 Java 和 Python 的跨账户访问。有关详细的实现指南,请查阅 Kinesis Data Analytics 的 AWS 文档页面。
  • AWS Glue Streaming – AWS Glue 的文档描述了如何配置 AWS Glue 流式 ETL 作业以访问跨账户的 Kinesis Data Streams。
  • AWS Lambda – Lambda 目前不支持从 Amazon Kinesis 进行跨账户调用,但可以使用一种解决方法。

在本博客文章中,我们将为您介绍配置 KCL 以实现跨账户访问 Kinesis Data Streams 的步骤。

方案概要

如以下架构图所示,账户 A 拥有 Kinesis 数据流,而账户 B 则有从账户 A 的 Kinesis 数据流中消费的 KCL 实例。在本博客文章中,KCL 代码在 Amazon Elastic Compute Cloud(Amazon EC2)上运行。

从账户 B 的 KCL 应用程序中访问账户 A 中的 Kinesis 数据流的步骤如下:

  1. 在账户 A 中创建用于访问 Kinesis 数据流的 AWS Identity and Access Management(IAM)角色,将此角色建立与账户 B 的信任关系。
  2. 在账户 B 中创建 IAM 角色,以扮演账户 A 中的角色。该角色将附加到运行 KCL 应用程序的 EC2 实例组。
  3. 访问验证,在账户 B 中扮演账户 A 中的角色,以读取账户 A 中的 Kinesis 数据流。

架构图

配置步骤

第一步 – 在账户 A 中创建 IAM 策略和 IAM 角色

首先,我们将在账户 A 中创建一个 IAM 角色,该角色具有访问在同一账户中创建的 Kinesis 数据流的权限。我们还需将账户 B 添加为该角色的受信任实体。

1. 创建名为 kds-poc-stream-policy 的 IAM 策略,用以访问账户 A 中的 Kinesis 数据流。策略定义如下,该策略限制对特定 Kinesis 数据流的访问。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt123",
            "Effect": "Allow",
            "Action": [
                "kinesis:DescribeStream",
                "kinesis:GetShardIterator",
                "kinesis:GetRecords",
                "kinesis:ListShards",
                "kinesis:DescribeStreamSummary",
                "kinesis:RegisterStreamConsumer"
            ],
            "Resource": [
                "arn:aws:kinesis:us-east-1:Account-A-AccountNumber:stream/PocStream"
            ]
        },
        {
            "Sid": "Stmt234",
            "Effect": "Allow",
            "Action": [
                "kinesis:SubscribeToShard",
                "kinesis:DescribeStreamConsumer"
            ],
            "Resource": [
                "arn:aws:kinesis:us-east-1:Account-A-AccountNumber:stream/PocStream/*"
            ]
        }
    ]
}

注意:上述策略假设 Kinesis 数据流的名称为 PocStream。

2. 在账户 A 中创建名为 kds-poc-stream-role 的 IAM 角色。

aws iam create-role --role-name kds-poc-stream-role --assume-role-policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam::Account-B-AccountNumber:root\"]},\"Action\":[\"sts:AssumeRole\"]}]}"

3. 将 kds-poc-stream-policy IAM 策略附加到 kds-poc-stream-role 角色上。

aws iam attach-role-policy --policy-arn arn:aws:iam::Account-A-AccountNumber:policy/kds-poc-stream-policy --role-name kds-poc-stream-role

在上述步骤中,您需要将 Account-A-AccountNumber 替换为拥有 Kinesis 数据流的 AWS 账户的账户号,将 Account-B-AccountNumber 替换为拥有 KCL 应用程序的 AWS 账户的账户号。

第二步 – 在账户 B 中创建 IAM 策略和 IAM 角色

我们将在账户 B 中创建一个 IAM 角色,以扮演在第一步中在账户 A 中创建的角色。该角色还将授予 KCL 应用程序访问账户 B 中的 Amazon DynamoDB 和 Amazon CloudWatch 的权限。对于每个 KCL 应用程序,都会使用一个 DynamoDB 表来跟踪 Kinesis 数据流中由 KCL 消费者应用程序的工作进程租用和处理的分片。DynamoDB 表的名称与 KCL 应用程序的名称相同。类似地,KCL 应用程序需要访问 CloudWatch 发送指标。由于 KCL 应用程序在账户 B 中运行,我们希望将 DynamoDB 表和 CloudWatch 指标与应用程序代码保持在同一账户中。在本博客文章中,我们的 KCL 应用程序名称为 PocProcessor。

1. 创建名为 kcl-poc-app-policy 的 IAM 策略,该策略具有在账户 B 中访问 DynamoDB 和 CloudWatch 的权限,并且可以扮演在账户 A 中创建的 kds-poc-stream-role 角色。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AssumeRoleInSourceAccount",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::Account-A-AccountNumber:role/kds-poc-stream-role"
        },
        {
            "Sid": "Stmt456",
            "Effect": "Allow",
            "Action": [
                "dynamodb:CreateTable",
                "dynamodb:DescribeTable",
                "dynamodb:Scan",
                "dynamodb:PutItem",
                "dynamodb:GetItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:us-east-1:Account-B-AccountNumber:table/PocProcessor"
            ]
        },
        {
            "Sid": "Stmt789",
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricData"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

上述策略允许访问 DynamoDB 表 PocProcessor。如果您更改了 KCL 应用程序的名称,请确保相应地更改上述策略以反映相应的 DynamoDB 表名称。

2. 在账户 B 中创建角色 kcl-poc-app-role,以扮演账户 A 中的角色。

aws iam create-role --role-name kcl-poc-app-role --assume-role-policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}"

3. 将策略 kcl-poc-app-policy 附加到角色 kcl-poc-app-role 上。

aws iam attach-role-policy --policy-arn arn:aws:iam::Account-B-AccountNumber:policy/kcl-poc-app-policy --role-name kcl-poc-app-role

4. 创建一个实例配置文件,名称为 kcl-poc-app-role。

aws iam create-instance-profile --instance-profile-name kcl-poc-app-role

5. 将 kcl-poc-app-role 角色附加到实例配置文件上。

aws iam add-role-to-instance-profile --instance-profile-name kcl-poc-app-role --role-name kcl-poc-app-role

6. 将 kcl-poc-app-role 角色附加到运行 KCL 代码的 EC2 实例上。

aws ec2 associate-iam-instance-profile --iam-instance-profile Name=kcl-poc-app-role --instance-id <your EC2 instance>

在上述步骤中,您需要将 Account-A-AccountNumber 替换为拥有 Kinesis 数据流的 AWS 账户的账户号,将 Account-B-AccountNumber 替换为拥有 KCL 应用程序的 AWS 账户的账户号,将 <your EC2 instance id> 替换为正确的 EC2 实例 ID。此实例配置文件应添加到启动的任何新的 KCL 应用程序的 EC2 实例中。

访问验证

访问验证的思路就是从账户 B 中,通过扮演账户 A 中的角色,以读取账户 A 中的 Kinesis 数据流。操作方法如下:

在 EC2 上,运行此命令来扮演账户 A 中的 kds-poc-stream-role:

aws sts assume-role —role-arn arn:aws:iam::Account-A-AccountNumber:role/kds-poc-stream-role —role-session-name kds-crossaccount-test

然后运行以下命令来读取账户 A 中 shard 的信息:

aws kinesis get-shard-iterator —stream-arn arn:aws:kinesis:us-east-1:Account-A-AccountNumber:stream/PocStream —shard-id shardId-000000000003 —shard-iterator-type TRIM_HORIZON —region us-east-1

请注意,这里需要将 Account-A-AccountNumber 替换为拥有 Kinesis 数据流的 AWS 账户的账户号,shardId-000000000003 替换为您实际的 shardId,TRIM_HORIZON 替换为您实际的 shard-iterator-type,us-east-1 替换为您实际的 region 信息。

总结

本文主要介绍了如何为 Amazon Kinesis Data Streams 启用跨账户访问,本文是以 KCL 为例来做介绍的,实际上,此方法对 KPL 也依然适用。另外,对于 AWS 大部分的服务,在做跨账户访问的权限配置时(账户 B 需要访问账户 A 中的资源),总体思路您都可以参考本文介绍到的方法:

  1. 在账户 A 中创建具有访问相应资源权限的 IAM 角色 1,且该角色信任账户 B。
  2. 在账户 B 中创建 IAM 角色 2,该角色具有扮演账户 A 中的角色 1 的权限。
  3. 在账户 B 中通过让 IAM 角色 2 扮演账户 A 中的角色 1 来访问账户 A 中的资源。

只是不同的场景下,需要赋予角色不同的权限,这个需要根据实际情况而定,后续我们也会针对一些典型场景持续输出操作方法文档。

本篇作者

任田田

AWS 解决方案架构师,负责基于 AWS 云计算方案架构的咨询和设计,推广 AWS 云平台技术和各种解决方案。

付小飞

AWS 资深解决方案架构师,负责基于 AWS 的云计算方案的咨询与架构设计。专注于游戏行业,帮助客户利用 AWS 全球基础设施与强大的技术能力打造爆款游戏,降低游戏运行成本。