配置对 Amazon DynamoDB 的跨账户访问 - AWS 规范指引

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

配置对 Amazon DynamoDB 的跨账户访问

Shashi Dalmia、Imhoertha Ojior 和 Esteban Serna Parra,Amazon Web Services

Summary

此模式说明了使用基于资源的策略来配置对 Amazon DynamoDB 的跨账户访问的步骤。对于使用 DynamoDB 的工作负载而言,采用工作负载隔离策略来最大限度地降低安全威胁并满足合规性要求已日渐盛行。实施工作负载隔离策略通常需要使用 AWS Identity and Access Management 基于身份的 (IAM) 策略跨账户和跨区域访问 DynamoDB 资源。这包括设置 IAM 权限并在两者之间建立信任关系 AWS 账户。

DynamoDB 基于资源的策略极大地简化了跨账户工作负载的安全态势。此模式提供了步骤和示例代码,用于演示如何将 AWS Lambda 函数合而为一, AWS 账户 以便将数据写入其他账户的 DynamoDB 数据库表。

先决条件和限制

先决条件

  • 两个活跃 AWS 账户。此模式将这些账户称为账户 A账户 B

  • AWS Command Line Interface (AWS CLI) 已安装配置为访问账户 A,以创建 DynamoDB 表。此模式中的其他步骤提供了有关使用 IAM、DynamoDB 和 Lambda 控制台的说明。如果您打算 AWS CLI 改用,请将其配置为同时访问两个帐户。

限制

架构

下图显示了单账户架构。 AWS Lambda、亚马逊 Elastic Compute Cloud(亚马逊 EC2)和 DynamoDB 都在同一个账户中。在这种情况下,Lambda 函数和亚马逊 EC2 实例可以访问 DynamoDB。要授予对 DynamoDB 表的访问权限,您可以在 IAM 中创建基于身份的策略,也可以在 DynamoDB 中创建基于资源的策略。

使用 IAM 权限访问同一账户中的 DynamoDB 表。

下图显示了多账户架构。如果一个中的资源 AWS 账户 需要访问其他账户中的 DynamoDB 表,则需要在 DynamoDB 中设置基于资源的策略来授予所需的访问权限。例如,在下图中,使用基于资源的策略向账户 B 中的 Lambda 函数授予访问账户 A 中的 DynamoDB 表的权限。

使用基于资源的策略以访问另一账户中的 DynamoDB 表。

此模式描述了 Lambda 和 DynamoDB 之间的跨账户访问。 AWS 服务 如果两个账户都配置了相应的权限,则可以对其他账户使用类似的步骤。例如,如果您想向 Lambda 函数提供对账户 A 中 Amazon Simple Storage Service(Amazon S3)存储桶的访问权限,则可以在 Amazon S3 中创建基于资源的策略,并将权限添加到账户 B 中的 Lambda 执行角色。

工具

AWS 服务

  • Amazon DynamoDB 是一项完全托管式 NoSQL 数据库服务,可提供快速、可预测、可扩展的性能。

  • AWS Identity and Access Management (IAM) 通过控制谁经过身份验证并有权使用您的 AWS 资源,从而帮助您安全地管理对这些资源的访问。

  • AWS Lambda 是一项计算服务,可帮助您运行代码,无需预调配或管理服务器。它只在需要时运行您的代码,并自动进行扩展,因此您只需为使用的计算时间付费。

代码

此模式包含其他信息部分中的示例代码,展示了如何在账户 B 中配置 Lambda 函数以写入账户 A 中的 DynamoDB 表。提供的代码仅供说明和测试之用。如果您在生产环境中实现此模式,请使用代码作为参考并针对您自己的环境进行自定义。

最佳实践

操作说明

Task说明所需技能

在账户 B 中创建策略。

此 IAM 策略允许对账户 A 中的 DynamoDB 表PutItem执行操作。

  1. 在中登录账户 B AWS 管理控制台。

  2. 打开 IAM 控制台

  3. 在导航窗格中,选择 策略,然后选择 创建策略

  4. 指定权限页面上,对于策略编辑器,选择 JSON

  5. 输入以下策略。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Action": "dynamodb:PutItem", "Resource": "arn:aws:dynamodb:<Region>:<Account-A-ID>:table/Table-Account-A" } ] }
  6. <Region><Account-A-ID> 替换为您的值,然后选择下一步

  7. 对于策略名称,输入策略的唯一名称,如 DynamoDB-PutItem-Policy

  8. (可选)添加策略描述。

  9. 选择创建策略

常规 AWS

在账户 B 中创建角色。

账户 B 中的 Lambda 函数使用此 IAM 角色访问账户 A 中的 DynamoDB 表。

  1. 打开 IAM 控制台

  2. 在导航窗格中,选择角色,然后选择创建角色

  3. 对于 Select trusted entity(选择受信任实体),选择 AWS 服务

  4. 使用案例部分,选择 Lambda

  5. 选择下一步: 权限

  6. 筛选器策略框中,输入 DynamoDB

  7. 在 DynamoDB 策略列表中,选择 DynamoDB-PutItem-Policy

  8. 清除筛选策略框,然后输入 Lambda

  9. 在 Lambda 策略列表中,选择AWSLambda执行。

  10. 选择下一步:名称、查看并创建

  11. 对于 Role name(角色名称),请为角色输入唯一名称,例如 DynamoDB-PutItemAccess

  12. (可选)添加角色描述。

  13. (可选)以键值对形式附加标签来向角色添加元数据。

  14. 选择创建角色

有关创建角色的更多信息,请参阅 IAM 文档

常规 AWS

记下 角色 ARN。

  1. 打开 IAM 控制台

  2. 在导航窗格中,选择角色

  3. 在搜索框中输入 DynamoDB-PutItemAccess,然后选择角色。

  4. 在角色摘要页面中,复制 Amazon 资源名称(ARN)。设置 Lambda 函数时,您可以使用 ARN。

常规 AWS
Task说明所需技能

创建 DynamoDB 表。

使用以下 AWS CLI 命令创建 DynamoDB 表。

aws dynamodb create-table \ --table-name Table-Account-A \ --attribute-definitions \ AttributeName=category,AttributeType=S \ AttributeName=item,AttributeType=S \ --key-schema \ AttributeName=category,KeyType=HASH \ AttributeName=item,KeyType=RANGE \ --provisioned-throughput \ ReadCapacityUnits=5,WriteCapacityUnits=5 \ --resource-policy \ '{ "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<Account-B-ID>:role/<Role-Name>" }, "Action": "dynamodb:PutItem", "Resource": "arn:aws:dynamodb:<Region>:<Account-A-ID>:table/Table-Account-A" } ] }'

在此代码命令示例中,替换以下内容:

  • <Account-B-ID> 是账户 B 的 ID。

  • <Role-Name> 是您创建的 IAM 角色的名称,例如 DynamoDB-PutItemAccess

  • <Region>是您创建 DynamoDB 表 AWS 区域 的地方。

  • <Account-A-ID> 是账户 A 的 ID。

注意

您可以使用 --resource-policy 标志在 create-table 语句中指定基于资源的策略配置。此策略引用账户 A 中 DynamoDB 表的 ARN

有关创建表的更多信息,请参阅 DynamoDB 文档

常规 AWS
Task说明所需技能

创建一个 Lambda 函数,以向 DynamoDB 写入数据。

  1. 在中登录账户 B AWS 管理控制台。

  2. 打开 Lambda 控制台

  3. 在导航窗格中,选择函数,然后选择创建函数

  4. 对于名称,请输入 lambda_write_function

  5. 对于运行时系统,请选择 Python 3.8 或更高版本。

  6. 更改默认执行角色下,选择使用现有角色

  7. 对于现有角色,选择您创建的 IAM 角色,例如 DynamoDB-PutItemAccess

  8. 选择创建函数

  9. 代码选项卡中,粘贴此模式中的其他信息部分提供的示例代码。在此代码命令示例中,替换以下内容:

    • <Account-A-ID> 是账户 A 的 ID。

    • <Region>是您创建 DynamoDB 表 AWS 区域 的地方。

  10. 选择部署

  11. 选择测试。这将提示您配置测试事件。使用您的首选名称创建一个新事件,例如 MyTestEventForWrite,然后保存配置。

  12. 再次选择 Test (测试)。这会使用您提供的事件名称运行 Lambda 函数。

  13. 检查函数输出。这应该会表明该函数访问了账户 A 中的 DynamoDB 表并且能够向其中写入数据。

有关创建 Lambda 函数的更多信息,请参阅 Lambda 文档

常规 AWS
Task说明所需技能

删除资源。

要避免产生与在此模式中创建的资源相关的成本,请执行以下操作,删除这些资源:

  1. 在账户 B 中,删除您为连接至 DynamoDB 而创建的 Lambda 函数。有关说明,请参阅 Lambda 文档

  2. 在账户 A 中,删除您创建的 DynamoDB 表。有关说明,请参阅 DynamoDB 文档

  3. 有关安全最佳实践,请在不再需要 IAM 策略 (DynamoDB-PutItem-Policy) 时将其删除。有关更多信息,请参阅 IAM 文档

  4. 有关安全最佳实践,请在不再需要 IAM 角色 (DynamoDB-PutItemAccess) 时将其删除。有关更多信息,请参阅 IAM 文档

常规 AWS

问题排查

问题解决方案

在创建 Lambda 函数时,您会收到 ResourceNotFoundException 错误。

确认您已正确输入账户 A 的 AWS 区域 和 ID。这些是 DynamoDB 表的 ARN 的一部分。

相关资源

附加信息

示例代码

import boto3 from datetime import datetime dynamodb_client = boto3.client('dynamodb') def lambda_handler(event, context): now = datetime.now().isoformat() data = dynamodb_client.put_item(TableName='arn:aws:dynamodb:<Region>:<Account-A-ID>:table/Table-Account-A', Item={"category": {"S": "Fruit"},"item": {"S": "Apple"},"time": {"S": now}}) return data
注意

对 DynamoDB 客户端执行实例化时,将提供 DynamoDB 表的 ARN,而不是表名。这是必备项,这样 Lambda 函数才能在运行时连接到正确的 DynamoDB 表。