跨账户将数据从 Amazon Redshift 集群卸载到亚马逊 S3 - AWS Prescriptive Guidance

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

跨账户将数据从 Amazon Redshift 集群卸载到亚马逊 S3

由安德鲁·卡梅尔创作 () AWS

代码存储库:aws-unload-redshift-to- s3-python

环境:生产

技术:数据库;分析;无服务器

工作负载:开源

AWS服务:AWSLambda;亚马逊 Redshift;亚马逊 S3;Secrets Manager AWS

Summary

在测试应用程序时,将生产数据放在测试环境中会很有帮助。使用生产数据可以更准确地评估正在开发的应用程序。

这种模式将数据从生产环境中的 Amazon Redshift 集群提取到亚马逊网络服务开发环境中的亚马逊简单存储服务 (Amazon S3) 存储桶 ()。AWS

该模式将逐步完成两个PROD账户DEV的设置,包括以下内容:

  • 所需的 资源

  • AWS Identity and Access Management (IAM) 角色

  • 对子网、安全组和虚拟私有云 (VPC) 进行网络调整,以支持 Amazon Redshift 连接

  • 一个带有 Python 运行时的示例 AWS Lambda 函数,用于测试架构

要授予对 Amazon Redshift 集群的访问权限,该模式 AWS Secrets Manager 用于存储相关证书。好处是拥有直接连接到 Amazon Redshift 集群所需的所有信息,而无需知道 Amazon Redshift 集群所在的位置。此外,您还可以监控密钥的使用情况

Secrets Manager 中保存的密钥包括 Amazon Redshift 集群的主机、数据库名称、端口和相关凭证。

有关使用此模式时的安全注意事项的信息,请参阅 “最佳实践” 部分。

先决条件和限制

先决条件

限制

  • 根据您要查询的数据量,Lambda 函数可能会超时。

    如果您的运行时间超过了 Lambda 的最大超时时间(15 分钟),请对您的 Lambda 代码使用异步方法。此模式的代码示例使用适用于 Python 的 psycopg2 库,该库目前不支持异步处理。

  • 有些 AWS 服务 并非全部可用 AWS 区域。有关区域可用性,请参阅AWS 服务 按地区划分。有关特定终端节点,请参阅服务终端节点和配额页面,然后选择服务的链接。

架构

下图显示了带有DEV和PROD帐户的目标架构。

账户中的 Lambda 和DEV账户VPC中的 Amazon VPC Redshift。PROD

图表显示了以下工作流:

  1. 账户中的 Lambda 函数担任访问DEV账户中 Secrets Manager 中的 Amazon Redshift 凭证所需的IAM角色。PROD

    然后,Lambda 函数检索亚马逊 Redshift 集群密钥。

  2. 账户中的 Lambda 函数使用这些信息通过对等连接连接到DEV账户中的 Amazon Redshift 集群。PROD VPCs

    然后,Lambda 函数发送卸载命令来查询账户中的 Amazon Redshift 集群。PROD

  3. 账户中的 Amazon Redshift 集群IAM扮演访问PROD账户中的 S3 存储桶的相关角色。DEV

    Amazon Redshift 集群将查询的数据卸载到账户中的 S3 存储桶。DEV

查询来自亚马逊 Redshift 的数据

下图显示了用于检索亚马逊 Redshift 凭证和连接到亚马逊 Redshift 集群的角色。该工作流程由 Lambda 函数启动。

跨账户担任角色的三步流程。

图表显示了以下工作流:

  1. DEV账户CrossAccount-SM-Read-Role中的假设是PROD账户SM-Read-Role中的。

  2. SM-Read-Role角色使用附加的策略从 Secrets Manager 中检索密钥。

  3. 这些证书用于访问亚马逊 Redshift 集群。

将数据上传到亚马逊 S3

下图显示了提取数据并将其上传到 Amazon S3 的跨账户读写过程。该工作流程由 Lambda 函数启动。这些模式在 Amazon Redshift 中IAM扮演角色链。来自 Amazon Redshift 集群的卸载命令假定CrossAccount-S3-Write-Role为,然后假设。S3-Write-Role这种角色链允许亚马逊 Redshift 访问亚马逊 S3。

获取证书、访问 Amazon Redshift 以及将数据上传到亚马逊 S3 的角色。

该工作流程包括以下步骤:

  1. DEV账户CrossAccount-SM-Read-Role中的假设是PROD账户SM-Read-Role中的。

  2. 从 Secrets Manager 中SM-Read-Role检索亚马逊 Redshift 凭证。

  3. Lambda 函数连接到 Amazon Redshift 集群并发送查询。

  4. Amazon Redshift 集群假设. CrossAccount-S3-Write-Role

  5. CrossAccount-S3-Write-Role假设DEV账户S3-Write-Role中有。

  6. 查询结果将卸载到DEV账户中的 S3 存储桶中。

工具

AWS 服务

  • AWS Key Management Service (AWS KMS) 可帮助您创建和控制加密密钥以帮助保护您的数据。

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

  • Amazon Redshift 是一项托管的 PB 级云端数据仓库服务。AWS

  • AWS Secrets Manager通过API调用 Secrets Manager 以编程方式检索密钥,帮助您替换代码中的硬编码凭据(包括密码)。

  • Amazon Simple Storage Service (Amazon S3) 是一项基于云的对象存储服务,可帮助您存储、保护和检索任意数量的数据。

代码存储库

此模式的代码可在 GitHub unload-redshift-to-s3-python 存储库中找到。

最佳实践

安全免责声明

在实施此解决方案之前,请考虑以下重要的安全建议:

  • 请记住,连接开发和生产帐户可能会扩大范围,降低整体安全状况。我们建议仅临时部署此解决方案,提取所需的数据部分,然后立即销毁已部署的资源。要销毁资源,您应删除 Lambda 函数,删除为此解决方案创建的所有IAM角色和策略,并撤消在账户之间授予的任何网络访问权限。

  • 在将任何数据从生产环境复制到开发环境之前,请咨询您的安全和合规团队。通常不应以这种方式复制个人身份信息 (PIIPHI)、受保护的健康信息 () 以及其他机密或受监管的数据。仅复制公开可用的非机密信息(例如,商店前端的公开库存数据)。尽可能考虑对数据进行标记化或匿名化处理,或者生成合成测试数据,而不是使用生产数据。AWS 安全原则之一是让人们远离数据。换句话说,开发者不应在生产账户中执行操作。

  • 限制对开发账户中的 Lambda 函数的访问,因为它可以在生产环境中从 Amazon Redshift 集群中读取数据。

  • 为避免中断生产环境,请实施以下建议:

    • 使用单独的专用开发帐户进行测试和开发活动。

    • 实施严格的网络访问控制,将账户之间的流量限制在必要的范围内。

    • 监控和审核对生产环境和数据源的访问权限。

    • 对所有涉及的资源和服务实施最低权限访问控制。

    • 定期审查和轮换证书,例如 AWS Secrets Manager 密钥和IAM角色访问密钥。

  • 有关本文中使用的服务,请参阅以下安全文档:

访问生产数据和资源时,安全性是重中之重。始终遵循最佳实践,实施最低权限访问控制,并定期审查和更新您的安全措施。

操作说明

任务描述所需技能

为亚马逊 Redshift 集群创建密钥。

要为 Amazon Redshift 集群创建密钥,请执行以下操作:

  1. 在PROD账户中,登录并打开 Secret AWS Management Console s Manager 控制台,网址为 https://console.aws.amazon.com/secretsmanager/。

  2. 选择 “存储新密钥”。

  3. 选择 Amazon Redshift 数据仓库的凭证

  4. 用户名密码中,输入您的实例的值,然后确认或选择加密密钥的值。

  5. 选择您的密钥将访问的 Amazon Redshift 数据仓库。

  6. 输入Redshift-Creds-Secret机密名称。

  7. 使用默认选项完成剩余的创建步骤,然后选择存储

  8. 查看您的密钥,并记下为识别密钥而生成的密钥ARN值。

DevOps 工程师

创建一个角色来访问 Secrets Manager。

要创建角色,请执行以下操作:

  1. 在PROD账户中,打开IAM控制台,网址为 https://console.aws.amazon.com/iam/。

  2. 选择策略

  3. 选择创建策略

  4. 选择JSON选项卡,然后输入如下所示的IAM策略:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetResourcePolicy", "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds" ], "Resource": [ "<Redshift-Creds-Secret-ARN>" ] }, { "Effect": "Allow", "Action": "secretsmanager:ListSecrets", "Resource": "*" } ] }

    Redshift-Creds-Secret-ARN替换为 Secrets Manager 密钥的亚马逊资源名称 (ARN),该密钥包含 Amazon Redshift 集群的信息和证书。

DevOps 工程师
任务描述所需技能

创建用于访问 S3 存储桶的角色。

要创建用于访问 S3 存储桶的角色,请执行以下操作:

  1. 在DEV账户中,打开IAM控制台。

  2.  选择策略

  3. 选择创建策略

  4.  选择JSON选项卡,然后输入如下所示的IAM策略:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "kmsstmt", "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKey" ], "Resource": [ "<kms-key-arn>" ] }, { "Sid": "s3stmt", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:Get*", "s3:List*" ], "Resource": [ "arn:aws:s3:::mybucket", "arn:aws:s3:::mybucket/*" ] } ] }

    mybucket替换为您要访问的 S3 存储桶的名称。此外,如果 S3 存储桶已加密,请kms-key-arn替换ARN为用于加密 S3 存储桶的 AWS Key Management Service (AWS KMS) 密钥。否则,您就不需要政策中的 AWS KMS 章节了。

  5. 选择查看策略,输入S3-Write-Policy作为策略名称,然后选择创建策略

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

  7.  选择 Create role(创建角色)。

  8. 对于可信实体角色,请选择自定义信任策略

  9. 选择 “下一步:权限”,然后选择您创建的 S3-Write-Policy 策略

  10. 输入S3-Write-Role角色名称,然后选择创建角色

DevOps 工程师

创建 Amazon Redshift 角色。

要创建 Amazon Redshift 角色,请执行以下操作:

  1. 在PROD账户中,打开IAM控制台。

  2. 选择策略

  3. 选择创建策略

  4. 选择JSON选项卡,然后输入如下所示的IAM策略:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "CrossAccountPolicy", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "S3-Write-Role-ARN" } ] }

    S3-Write-Role-ARN替换ARN为DEV账户S3-Write-Role中的。

  5. 选择查看策略,输入S3-Write-Role-Assume-Policy作为策略名称,然后选择创建策略

  6. 在导航窗格中,选择 Roles(角色),然后选择 Create role(创建角色)

  7. 选择AWS服务作为您的可信实体类型,然后选择 Redshift、Redshift-可自定义。

  8. 选择 “下一步:权限”,然后选择您创建的 S3-Write-Role-Assume- Policy 策略。

  9. 输入CrossAccount-S3-Write-Role角色名称,然后选择创建角色

  10. 将该IAM角色与您的亚马逊 Redshift 集群相关联

DevOps 工程师
任务描述所需技能

部署 Lambda 函数。

要在对等互连设备中部署 Lambda 函数VPC,请执行以下操作:

  1. 打开 Lambda 控制台,网址为。 https://console.aws.amazon.com/lambda/

  2. 选择 函数

  3. 选择 Create function(创建函数)。

  4. 基本信息下的函数名称中输入函数的名称。

  5. 对于运行时,选择 Python 3.8

  6. 展开 “更改默认执行角色”,然后执行以下操作:

    1. 选择 “使用现有角色”。

    2. 对于现有角色,请选择您之前创建的 CrossAccount-rm-read-role Lambda 角色

  7. 展开 “高级设置”,然后执行以下操作:

    1. 选中 “启用” VPC 复选框。

    2. 对于 VPC,选择DEV账户VPC中的对等用户。

    3. 对于子网,请选择私有子网。

    4. 对于 Security groups (安全组),选择默认安全组。

  8. 选择 Create function (创建函数)

  9. psycopg2 库作为一个添加到 Lambda 函数中。

    注意:你可以使用 psycopg 2-lambda-layer 存储库中已经部署的层。请务必使用URL基于你的 AWS 区域 和 Python 运行时。

DevOps 工程师
任务描述所需技能

导入所需的资源。

要导入所需的资源,请运行以下命令:

import ast import boto3 import psycopg2 import base64 from botocore.exceptions import ClientError
应用程序开发人员

运行 Lambda 处理程序函数。

Lambda 函数使用 AWS Security Token Service (AWS STS) 进行跨账户访问和临时凭证管理。该函数使用该 AssumeRole API操作来临时承担该sm_read_roleIAM角色的权限。

要运行 Lambda 函数,请使用以下示例代码:

def lambda_handler(event, context): sts_client = boto3.client('sts') # Secrets Manager Configurations secret_name = "redshift_creds" sm_region = "eu-west-1" sm_read_role = "arn:aws:iam::PROD_ACCOUNT_NUMBER:role/SM-Read-Role" # S3 Bucket Configurations s3_bucket_path = "s3://mybucket/" s3_bucket_region = "eu-west-1" s3_write_role = "arn:aws:iam::DEV_ACCOUNT_NUMBER:role/S3-Write-Role" # Redshift Configurations sql_query = "select * from category" redshift_db = "dev" redshift_s3_write_role = "arn:aws:iam::PROD_ACCOUNT_NUMBER:role/CrossAccount-S3-Write-Role" chained_s3_write_role = "%s,%s" % (redshift_s3_write_role, s3_write_role) assumed_role_object = sts_client.assume_role( RoleArn=sm_read_role, RoleSessionName="CrossAccountRoleAssumption", ExternalId="YOUR_EXTERNAL_ID", ) credentials = assumed_role_object['Credentials'] secret_dict = ast.literal_eval(get_secret(credentials, secret_name, sm_region)) execute_query(secret_dict, sql_query, s3_bucket_path, chained_s3_write_role, s3_bucket_region, redshift_db) return { 'statusCode': 200 }
应用程序开发人员

明白秘密。

要获取 Amazon Redshift 密钥,请使用以下示例代码:

def get_secret(credentials, secret_name, sm_region): # Create a Secrets Manager client session = boto3.session.Session() sm_client = session.client( service_name='secretsmanager', aws_access_key_id=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_session_token=credentials['SessionToken'], region_name=sm_region ) try: get_secret_value_response = sm_client.get_secret_value( SecretId=secret_name ) except ClientError as e: print(e) raise e else: if 'SecretString' in get_secret_value_response: return get_secret_value_response['SecretString'] else: return base64.b64decode(get_secret_value_response['SecretBinary'])
应用程序开发人员

运行卸载命令。

要将数据卸载到 S3 存储桶,请使用以下示例代码。

def execute_query(secret_dict, sql_query, s3_bucket_path, chained_s3_write_role, s3_bucket_region, redshift_db): conn_string = "dbname='%s' port='%s' user='%s' password='%s' host='%s'" \ % (redshift_db, secret_dict["port"], secret_dict["username"], secret_dict["password"], secret_dict["host"]) con = psycopg2.connect(conn_string) unload_command = "UNLOAD ('{}') TO '{}' IAM_ROLE '{}' DELIMITER '|' REGION '{}';" \ .format(sql_query, s3_bucket_path + str(datetime.datetime.now()) + ".csv", chained_s3_write_role, s3_bucket_region) # Opening a cursor and run query cur = con.cursor() cur.execute(unload_command) print(cur.fetchone()) cur.close() con.close()
应用程序开发人员
任务描述所需技能

删除 Lambda 函数。

为避免产生计划外成本,请移除资源以及和账户之间的连接DEV。PROD

要删除 Lambda 函数,请执行以下操作:

  1. 打开 AWS Lambda 控制台,网址为 https://console.aws.amazon.com/lambda/。

  2. 找到并选择您创建的 Lambda 函数。

  3. 选择操作,然后选择删除

  4. 确认删除操作。

DevOps 工程师

移除IAM角色和策略。

从和PROD账户中移除IAM角色DEV和策略。

在DEV账户中,执行以下操作:

  1. 打开控制IAM台。

  2. 删除以下角色:

    • S3-Write-Role

    • CrossAccount-RM-Read-Role(Lambda 角色)

  3. 删除关联的策略:

    • S3-Write-Policy

    • 担任PROD账户角色的 CrossAccount 政策

在PROD账户中,执行以下操作:

  1. 打开控制IAM台。

  2. 删除以下角色:

    • SM-Read-Role

    • CrossAccount-S3-Write-Role

  3. 删除关联的策略:

    • 访问 Secrets Manager 的 CrossAccount 政策

    • S3-Write-Role-Assume-Policy

DevOps 工程师

在 Secrets Manager 中删除密钥。

要删除密钥,请执行以下操作:

  1. 在PROD账户中,打开 Secrets Manager 控制台。

  2. 找到并选择名为的密钥Redshift-Creds-Secret

  3. 选择操作,然后选择删除密钥

  4. 确认删除操作。

DevOps 工程师

移除VPC对等互连和安全组规则。

要删除对VPC等互连和安全组规则,请执行以下操作:

  1. 在PROD账户中,打开 Amazon EC2 控制台,网址为 https://console.aws.amazon.com/ec2/。

  2. 导航到安全组

  3. 查找 Amazon Redshift 集群使用的安全组。

  4. 编辑入站规则,并删除允许从DEV账户的 Lambda VPC 进行连接的规则。

  5. 导航到VPC对等连接,然后删除对等连接。

DevOps 工程师

从 S3 存储桶中移除数据。

要从 Amazon S3 中删除数据,请执行以下操作:

  1. 在DEV账户中,打开 Amazon S3 控制台,网址为 https://console.aws.amazon.com/s3/。

  2. 找到您用于存储数据的存储桶。

  3. 删除存储桶中的对象,或者如果不再需要整个存储桶,则将其删除。

DevOps 工程师

清理 AWS KMS 钥匙。

如果您创建了任何用于加密的自定义 AWS KMS 密钥,请执行以下操作:

  1. 打开 AWS KMS 控制台,网址为 https://console.aws.amazon.com/kms/。

  2. 找到为此模式创建的所有密钥。

  3. 安排删除密钥。(删除密钥需要等待一段时间)。

DevOps 工程师

查看并删除 Amazon CloudWatch 日志。

要删除日 CloudWatch 志,请执行以下操作:

  1. 打开 CloudWatch 控制台,网址为 https://console.aws.amazon.com/cloudwatch/。

  2. 检查是否有任何由您的 Lambda 函数或 Amazon Redshift 集群创建的日志组。

  3. 如果不再需要这些日志组,请将其删除。

DevOps 工程师

相关资源

其他信息

将数据从 Amazon Redshift 卸载到亚马逊 S3 后,您可以使用亚马逊 Athena 对其进行分析。

Amazon Athena 是一项大数据查询服务,在您需要访问大量数据时非常有用。您无需配置服务器或数据库即可使用 Athena。Athena 支持复杂查询,你可以在不同的对象上运行它。

与大多数人一样 AWS 服务,使用 Athena 的主要好处是,它在运行查询时提供了极大的灵活性,而不会增加复杂性。使用 Athena 时,您可以在 Amazon S3 中查询不同的数据类型,CSV例如JSON和,而无需更改数据类型。您可以查询来自各种来源的数据,包括外部数据 AWS。Athena 降低了复杂性,因为您不必管理服务器。在您运行查询之前,Athena 直接从 Amazon S3 读取数据,无需加载或更改数据。