亚马逊AWS官方博客
如何为 Amazon S3 中的 AWS KMS 加密数据启用跨账户 Amazon Redshift COPY 和 Redshift Spectrum 查询
关于 AWS Key Management Service (AWS KMS)
使用 AWS Key Management Service (AWS KMS),您可以对保护您的静态数据所用的加密密钥进行集中控制。您可以创建、导入、轮换、禁用、删除、定义使用策略,并审计加密您的数据所用的加密密钥的使用。AWS KMS 使用经过 FIPS 140-2 验证的加密模块保护您的主密钥的保密性和完整性。
AWS KMS 可与大多数 AWS 服务无缝集成。此集成意味着,您可以轻松使用客户主密钥 (CMK) 来控制对您存储在这些服务内的数据的加密。决定对 Amazon Redshift 等服务中的数据进行加密时,您可以选择使用 Amazon Redshift 在 KMS 中自动创建的 AWS 托管 CMK。您可以跟踪密钥的使用情况,但其管理由服务代表您进行。有些情况下,您可能需要直接控制 CMK 的生命周期或者想要允许其他账户使用它。在这些情况下,您可以创建并管理您自己的 CMK,Amazon Redshift 等 AWS 服务可以代表您使用它们。这些客户托管 CMK 可使您全面控制访问权限,以决定哪些人可以使用该密钥及其在何种条件下使用该密钥。AWS KMS 可与 AWS CloudTrail 集成,后者是提供用户、角色或 AWS 服务在 AWS KMS 中执行的操作记录的服务。
关于 Amazon Redshift 和 Redshift Spectrum
Amazon Redshift 是 AWS 上的一项 PB 级完全托管型数据仓库服务。它使用分布式大规模并行处理 (MPP)、水平扩展以满足使用要求的无共享架构。
Amazon Redshift Spectrum 是 Amazon Redshift 的一个特性,它将 Amazon Redshift 的分析能力扩展到数据仓库的本地磁盘中所存储的数据之外。换言之,Amazon Redshift Spectrum 可使您将 Amazon Redshift 的相同 ANSI SQL 语法用于 Amazon S3 数据湖中存储的数据。您可以使用外部表格执行此操作,无需先将数据提取到 Amazon Redshift 中。常用模式为,运行跨越 Amazon Redshift 本地存储的经常访问“热”数据和经济高效地存储在 Amazon S3 中的“暖/冷”数据的查询。该模式通过启用计算和存储的独立扩展满足上述模式需求,以此分离计算和存储。这意味着,您必须为未使用的计算容量付款,只需添加更多存储。更为重要的是,此方法可在数据湖与 Amazon Redshift 之间实现无缝互操作性。
Amazon Redshift COPY 命令支持以下 Amazon S3 加密类型:
- 使用 Amazon S3 托管的密钥 (SSE-S3) 进行的服务器端加密
- 使用 AWS KMS 托管的密钥 (SSE-KMS) 进行的服务器端加密
- 使用客户端的对称主密钥进行的客户端加密
Amazon Redshift COPY 命令不支持以下 Amazon S3 加密类型:
- 使用客户提供的密钥 (SSE-C) 进行的服务器端加密
- 使用 AWS KMS 托管的客户主密钥进行的客户端加密
- 使用客户提供的非对称主密钥进行的客户端加密
关于使用案例
出于各种原因,多账户 AWS 环境是客户共用的模式。对于 AWS 中的数据湖客户,其中一个常见原因是,要将数据资产的所有权从公司的不同业务单位中分离出来。同时,业务单位可能需要相互授予对其部分数据资产的访问权,以获得新的业务见解。
如下面的图所示,在我们的示例中,账户 A 拥有包含 SSE-KMS 加密数据的 S3 存储桶,账户 B 拥有启用了 Redshift Spectrum 的 Amazon Redshift 集群。账户 B 需要使用 COPY 命令访问要加载到 Amazon Redshift 集群的相同数据,并且还需要使用 Redshift Spectrum 进行查询。
解决方案演练
接下来,我们详细介绍支持此使用案例的几个不同选项。
先决条件
此解决方案假设您已拥有以下设置:
-
- 对同一个 AWS 区域中两个 AWS 账户(我们称之为账户 A 和 B)的访问权。*
- 向 AWS 账户授予 AdministratorAccess 策略(在生产中,应对其进行进一步限制)。
- 账户 A 是 AWS KMS 中的客户托管 CMK,具有以下属性:
- 别名为 kms_key_account_a
- 描述为 Cross Account KMS Key in Account A
- 管理员为当前 IAM 用户,您使用该用户登录 AWS 控制台并创建 KMS 密钥
- 账户 B 被添加为外部账户
复制并保存 CMK Amazon 资源名称 (ARN) 以便稍后使用
- 账户 A 使用 AWS 中的以下示例数据集:
- 账户 A 拥有称为 rs-xacct-kms-bucket 的 S3 存储桶,其存储桶加密选项通过早前创建的 KMS 密钥 kms_key_account_a 被设置为 AWS KMS。
- 使用下面的 AWS CLI 命令复制 Amazon Redshift 文档中的 AWS 示例数据集 SSB – 示例架构基准中的客户表数据。注意:由于存储桶名称在所有 AWS 客户中是全局统一的,您需要为测试运行指定一个唯一的存储桶名称。务必在以下命令中将 rs-xacct-kms-bucket 替换为您自己的存储桶名称:
- 复制完成后,从 S3 控制台中检查文件的 KMS 密钥 ID,如下所示。
- 账户 B 拥有一个 Amazon Redshift 集群:
- 集群名称为 rstest
- 它可被公开访问
- 它附加了一个称为 redshift_role_account_b 的 IAM 角色,具有下面两个托管的 IAM 策略:
- AmazonS3ReadOnlyAccess
- AWSGlueConsoleFullAccess
注意:务必将 redshift_role_account_b 更新为您自己的 IAM 角色。
您可以从客户端工具中成功设置数据库会话,例如笔记本电脑中设置 SQL Workbench。
* 本次演练使用 US-West-2(俄勒冈)区域中可公开访问的 AWS 示例数据集。因此,我们建议您使用 US-West-2(俄勒冈)区域进行测试运行,以降低因数据移动而造成的跨区域网络延迟和费用。
逐步演练
根据您希望将哪个账户的 AWS Glue 数据目录用于 Redshift Spectrum,有两个解决方案选项可供选择:
- 账户 B 中的 AWS Glue 数据目录
- 账户 A 中的 AWS Glue 数据目录
选项 1:账户 B 中的 AWS Glue 数据目录
设置权限
- 登录账户 A 的 AWS 控制台。然后,将 AWS 区域更改为 us-west-2(俄勒冈)。添加 rs-xacct-kms-bucket 存储桶的以下存储桶策略,以使账户 B (拥有 Amazon Redshift 集群 – rstest 的账户)可以访问该存储桶。
注意:将 <Account B> 替换为账户 B 的 AWS 账户 ID,将 rs-xacct-kms-bucket 替换为存储桶名称。
-
- 登录账户 B 的 AWS 控制台。然后,将 AWS 区域更改为 us-west-2(俄勒冈)。按下面所述创建 IAM 策略和角色:
a) 创建下面两个 IAM 权限策略:rs_xacct_bucket_policy,可授予账户 B 访问账户 A 中 S3 存储桶的权限,及 rs_xacct_kms_policy,可授予账户 B 访问账户 A 中 CMK 的权限。
策略名称:rs_xacct_kms_policy
注意:将 <ARN of kms_key_account_a from Account A> 替换为账户 A 中的 KMS 密钥 ARN。
策略名称: rs_xacct_bucket_policy
注意:将 rs-xacct-kms-bucket 替换为您的存储桶名称。
b) 为附加了以下 IAM 策略的 Amazon Redshift 服务创建称为 xacct_kms_role_account_b 的新 IAM 角色:
• rs_xacct_bucket_policy
• rs_xacct_kms_policy
• AWSGlueConsoleFullAccess
保存 IAM 角色的 Amazon 资源名称 (ARN)。稍后您将使用该名称。
c) 现在,我们来为 Amazon Redshift 在两个 IAM 角色 redshift_role_account_b 和 xacct_kms_role_account_b 之间设置 IAM 角色链。
要链接角色,您需要在角色之间建立信任关系。承担另一个角色的角色(例如角色 A)必须具有一个权限策略,该策略允许它承担下一个链接角色(例如角色 B)。同样地,传递权限的角色(角色 B)必须具有一个信任策略,该策略允许它将自己的权限传递给上一个链接角色(角色 A)。
链中的第一个角色必须为附加到 Amazon Redshift 集群的角色。第一个角色及承担链中下一个角色的每个后续角色都必须具有一个包含特定语句的策略。该语句对 sts:AssumeRole 操作及资源元素中下一个角色的 ARN 产生 Allow 影响。
在我们的示例中,角色 A 为 redshift_role_account_b,它需要权限策略 rs_xacct_assume_role_policy 来允许它承担角色 B(角色 B 为 xacct_kms_role_account_b)。两个 IAM 角色都归 AWS 账户 B 所有。
d) 我们来创建 IAM 权限策略 rs_xacct_assume_role_policy 并将该策略附加到 IAM 角色 redshift_role_account_b 中。
策略名称:rs_xacct_assume_role_policy
注意:替换 <ARN for IAM role xacct_kms_role_account_b from Account B>。
e) 通过选择编辑信任关系并将现有信任策略替换为以下内容来更改 IAM 角色 xacct_kms_role_account_b 的信任关系:
注意:将 <Account B> 替换为账户 B 的 AWS 账户 ID。
f) 创建称为 glue_service_role_account_b 的 AWS Glue 服务 IAM 角色,并附加以下策略:
• AWSGlueServiceRole(AWS 托管策略)
• rs_xacct_bucket_policy(早前创建的托管策略)
• rs_xacct_kms_policy(早前创建的托管策略)
注意:务必将 glue_service_role_account_b 更新为您自己的 IAM 角色。
执行 Amazon Redshift COPY
- 从您的查询工具登录 Amazon Redshift 集群并使用下面的 DDL 创建客户表。
2.现在,您可以成功运行下面的 COPY 语句。
注意:替换账户 B 中的 IAM 角色 ARN,用逗号隔开,周围不加任何空格。
3.运行下面的示例查询,以确认数据已成功加载。
为要查询的 Redshift Spectrum 设置 AWS Glue 数据目录表
现在,我们在账户 B 中创建 AWS Glue 爬网程序,以对相同的客户数据进行爬网,并按照下面的步骤在 AWS Glue 数据目录数据库 spectrumdb_account_b 中创建称为客户的表:
- 在 AWS Glue 控制台中导航至数据库并选择添加数据库以创建称为 spectrumdb_account_b 的 AWS Glue 数据目录数据库,如下所示。
- 在 AWS Glue 控制台中导航至爬网程序并选择添加爬网程序,如下所示。
- 如下所示创建爬网程序 customerxacct。
注意:爬网程序作业名称(在此案例中为 customerxacct)与爬网程序创建的表名称不同(经常容易混淆)。表名称从前缀中自动选择,文件夹名称从 S3 存储桶和文件夹结构中自动选择。如果需要,您还可以选择附加表名称前缀。
- 选择下一步进入客户表的数据存储详细信息,如下所示。
- 选择下一步进入添加另一个数据存储,我们保留默认设置否,因为我们没有要添加的任何其他数据存储。
- 选择下一步,为要使用的爬网程序选择早前创建的 IAM 角色 glue_service_role_account_b,如下所示。
- 选择下一步进入计划页面,然后选择您希望此爬网程序作业运行的计划。在此示例中,我们可以选择按需运行。
- 选择下一步,以将 AWS Glue 数据目录数据库 spectrumdb_account_b(早前通过创建外部架构命令创建)选为爬网程序输出位置。
- 选择下一步以进入查看页面。
- 查看详细信息后,选择完成以完成爬网程序的创建。
- 现在,我们通过如下所示选择作业并选择运行爬网程序来运行爬网程序作业。
- 等待作业完成。作业状态从正在开始改变为停止,再改变为就绪。您可以选择刷新按钮来了解最新状态。
- 如果作业失败,失败情况将记录在 Amazon CloudWatch Logs 中。要查看日志,请选择前面的屏幕截图中所示的日志,然后您将进入 CloudWatch Logs。
- 现在,我们进入 AWS Glue 数据目录数据库,以确保表格存在。
选择数据库,选择 spectrumdb_account_b 数据库,然后选择查看表,或选择数据库名称的超链接。您应该会看到如下所示的客户表。
- 选择客户超链接以进入外部表,详细信息如下。
由于数据文件没有标题记录,AWS Glue 爬网程序已分配一个默认的列命名约定,如前所示。对于客户表,该命名从列 0 到列 7
- 选择编辑架构并按照下面的映射分配适当的列名称。
c0 => c_custkey
c1 => c_name
c2 => c_address
c3 => c_city
c4 => c_nation
c5 => c_region
c6 => c_phone
c7 => c_mktsegment
完成时,选择保存。
执行 Redshift Spectrum 查询
现在,已在 AWS Glue 数据目录中创建客户表,下面我们来使用 Redshift Spectrum 查询该表。
- 从您的查询工具登录 Amazon Redshift 集群。
- 运行下面的语句,为 Redshift Spectrum 创建一个称为 spectrumxacct 的外部架构,以指向 AWS Glue 数据目录数据库。此数据库在账户 B 中为 spectrumdb_account_b,已在 AWS Glue 控制台中创建。
注意:替换账户 B 中的 IAM 角色 ARN,用逗号隔开,周围不加任何空格。
- 运行下面的示例查询,以确认 Redshift Spectrum 可以成功查询数据。
注意:Redshift Spectrum 使用账户 B 中的 AWS Glue 数据目录,而非账户 A。
选项 2:账户 A 中的 AWS Glue 数据目录
设置权限
1.登录账户 A 的 AWS 控制台,然后将 AWS 区域更改为 us-west-2(俄勒冈)。
-
-
a) 创建以下 IAM 策略:
• rs-xacct-bucket-policy,可授予对账户 A 中的 S3 存储桶的访问权限
• rs_xacct_kms_policy,可授予对账户 A 中的 CMK 的访问权限
策略名称:rs_xacct_bucket_policy
注意:将存储桶名称 rs-xacct-kms-bucket 替换为您的存储桶名称。
策略名称:rs_xacct_kms_policy
注意:将 <ARN of kms_key_account_a from Account A> 替换为账户 A 中的 KMS 密钥 ARN。
b) 为具有以下 IAM 策略的 Amazon Redshift 服务创建称为 xacct_kms_role_account_b 的新 IAM 角色:
• rs_xacct_bucket_policy
• rs_xacct_kms_policy
• AWSGlueConsoleFullAccess(此托管策略为 AWS Glue 数据目录提供必需权限)
保存 IAM 角色 ARN,供稍后使用。
c) 通过选择编辑信任关系并将现有信任策略替换为以下内容来更改 IAM 角色 xacct_kms_role_account_a 的信任关系:
注意:将 <Account B> 替换为账户 B 的 AWS 账户 ID。
d) 创建称为 glue_service_role_account_a 的 AWS Glue 服务 IAM 角色,并附加以下策略:
• AWSGlueServiceRole(AWS 托管策略)
• rs_xacct_bucket_policy(早前创建的托管策略)
• rs_xacct_kms_policy(早前创建的托管策略)
注意:务必将 glue_service_role_account_a 更新为您自己的 IAM 角色
2.登录账户 B 的 AWS 控制台,并在尚未选择的情况下,将 AWS 区域更改为 us-west-2(俄勒冈)。
a) 修改现有的 IAM 策略 rs_xacct_assume_role_policy,并将现有的 JSON 策略替换为以下内容:
注意:替换 <ARN for IAM role xacct_kms_role_account_a from Account A>。
执行 Amazon Redshift COPY
1.从您的查询工具登录 Amazon Redshift 集群并使用下面的 DDL 创建客户表。
2.现在,您应该能够成功地运行下面的 COPY 语句。
注意:替换 IAM 角色 ARN,用逗号隔开,周围不加任何空格。
3.运行示例查询,以验证数据已成功加载。
为要查询的 Redshift Spectrum 设置 AWS Glue 数据目录表
现在,我们在账户 A 中创建 AWS Glue 爬网程序,以对相同的客户数据进行爬网,并按照下面的步骤在账户 A 的 AWS Glue 数据目录数据库 spectrumdb_account_a 中创建称为客户的表:
按照选项 1 中列出的步骤操作,并使用下面的更改运行爬网程序:
- 这一次,在账户 A 中创建爬网程序(与选项 1 中的账户 B 相反)。
- 在账户 A 中创建 AWS Glue 数据目录数据库 spectrumdb_account_a(与账户 B 中的 spectrumdb_account_b 相反,然后为爬网程序选择该数据库以创建客户表。
- 提供 S3 路径的同时,选择选项我的账户中的指定路径 (与为选项 1 选择的另一个账户中的指定路径不同)。
- 确保将早前创建的 glue_service_role_account_a 用作 AWS Glue 服务 IAM 角色。=
执行 Redshift Spectrum 查询
现在,已在 AWS Glue 数据目录中创建客户表,下面我们来使用 Redshift Spectrum 查询该表。
1.从您的查询工具登录 Amazon Redshift 集群,并运行下面的语句。这将会为 Redshift Spectrum 创建一个称为 spectrumxacct2 的外部架构,该架构指向账户 A 中的 AWS Glue 数据目录数据库 spectrumdb_account_a(早前从 AWS Glue 控制台中创建)。
注意:替换 IAM 角色 ARN,用逗号隔开,周围不加任何空格。
2.运行下面的查询,该查询应成功运行。
注意:Spectrum 使用账户 A 中的 AWS Glue 数据目录,而非账户 B。
小结
此博文显示了如何使用 Redshift Spectrum 为 Amazon S3 中的示例 KMS 加密数据集设置跨账户 Amazon Redshift COPY 和查询的逐步演练。它演示了两种解决方案选项,可根据您希望将哪个账户的 AWS Glue 目录用于 Redshift Spectrum 进行选择。
如果您有任何问题或建议,请留言。
关于作者
Asim Kumar Sasmal 是AWS 专业服务部 Global Specialty Practice 的 IoT 高级数据架构师。他通过在 AWS 平台上提供专家技术咨询、最佳实践指导和实施服务,帮助 AWS 全球客户设计和构建数据驱动型解决方案。他热衷于从客户的要求出发进行逆向工作,帮助他们从大处着眼,并进行深入了解,以利用 AWS 平台的力量解决实际业务问题。