作者:Damon Cortesi
日期:2023年11月26日
类别:Amazon EMR, Amazon S3, 分析, 公告
在本篇文章中,我们将探讨如何通过 Amazon EMR 集成 Amazon S3 访问权限授予来简化权限管理,增强 Apache Spark作业的安全性与可扩展性。我们会详细介绍设置流程以及如何利用 AWS CloudFormation模板创建资源,并展示不同的场景来使用这些集成。同时,我们将特别说明如何进行跨账户访问权限的配置。
Amazon EMR 现已支持集成 Amazon S3 访问授予,从而简化了 S3权限管理,并允许您在更大范围内执行细粒度访问控制。这项技术能够有效地提高数据安全性,用户可根据需要设置相关权限,尤其适合有多账户需求的企业。
接下来的内容将分为几个部分,包括基本的前提条件、创建资源的过程、示例场景等。
在启动 AWS CloudFormation 堆栈之前,请确保您具备以下条件:
要使用 Amazon S3 访问权限,您需要一个版本为 6.15.0 或更高的 Amazon EMR 集群。请参考以下文档以获取更多信息,包括如何将 Amazon S3 访问权限与 、 和 结合使用。
为本次演示,我们假设您在组织中有两种不同类型的数据访问用户——具有读写权限的分析工程师和仅具有读取权限的业务分析师。我们将使用两种不同的 AWS IAM角色,但您也可以直接将自己的身份提供者连接到 IAM 身份中心。
以下是这一部分的架构图。AWS CloudFormation 堆栈将创建以下 AWS 资源:
资源 | 描述 |
---|---|
VPC 堆栈 | 包含私有和公有子网,用于 EMR Studio,路由表和 NAT 网关。 |
Amazon S3 存储桶 | 存储 EMR 产生的日志文件、Spark 代码和 Jupyter 笔记本。 |
包含样本数据的 S3 存储桶 | 用于配合 S3 访问权限使用的样本数据。 |
配置的 Amazon EMR 集群 | 使用运行时角色和 S3 访问权限的集群。 |
配置的 Amazon EMR Serverless 应用 | 使用 S3 访问权限的 Serverless 应用。 |
EMR Studio | 用户可以登录并使用 EMR Serverless 应用创建工作空间笔记本。 |
两个用于 EMR 作业运行的 AWS IAM 角色 | 一个具有写入权限,一个具有读取权限。 |
处理 S3 访问权限的 IAM 角色 | 在注册位置时能用于访问存储桶数据的角色。 |
开始操作,请完成以下步骤:
AWS CloudFormation 堆栈的创建大约需要 10-15 分钟。完成后,转到输出标签,您会发现以下步骤所需的信息。
首先,我们将创建 Amazon S3 访问权限资源。创建一个 S3 访问权限实例,创建一个 S3 访问权限位置,引用由 AWS CloudFormation堆栈创建的数据存储桶,该存储桶仅对我们创建的 AWS IAM 角色可访问,并为读写角色授予不同级别的访问权限。
bash aws s3control create-access-grants-instance \ --account-id <YOUR_ACCOUNT_ID>
接下来,创建一个新的 S3 访问权限位置。Amazon S3 访问权限通过提供 AWS IAM 凭证来工作,这些凭证可用于特定 S3 前缀的访问。S3访问权限位置将与一个 AWS IAM 角色相关联。
我们将有选择性地将 AWS IAM 角色的作用域限制为堆栈创建的存储桶。前往输出标签以查找替换以下代码片段中的值:
bash aws s3control create-access-grants-location \ --account-id <YOUR_ACCOUNT_ID> \ --location-scope "s3://<DATA_BUCKET>/" \ --iam-role-arn <DATA_BUCKET_ROLE>
记下响应中的 AccessGrantsLocationId
值。我们将在接下来的步骤中创建必要的 S3 访问权限,以限制对存储桶的读写访问。
s3control create-access-grant
允许对 "output/*" 前缀的 READWRITE 访问:bash aws s3control create-access-grant \ --account-id <YOUR_ACCOUNT_ID> \ --access-grants-location-id <LOCATION_ID_FROM_PREVIOUS_COMMAND> \ --access- grants-location-configuration S3SubPrefix="output/*" \ --permission READWRITE \ --grantee GranteeType=IAM,GranteeIdentifier=<DATA_WRITER_ROLE>
s3control create-access-grant
允许对相同前缀的仅 READ 访问:bash aws s3control create-access-grant \ --account-id <YOUR_ACCOUNT_ID> \ --access-grants-location-id <LOCATION_ID_FROM_PREVIOUS_COMMAND> \ --access- grants-location-configuration S3SubPrefix="output/*" \ --permission READ \ --grantee GranteeType=IAM,GranteeIdentifier=<DATA_READER_ROLE>
现在我们已经设置好 Amazon EMR 环境并通过 S3 访问权限授予角色的访问权限,值得注意的是,我们的 EMR 集群和 EMR Serverless应用的两个 AWS IAM 角色具有只允许访问我们的 EMR 工件存储桶的 IAM 策略。它们没有访问 S3 数据存储桶的 IAM 权限,而是使用 S3访问权限获取针对存储桶和前缀的短期凭证。
此外,角色被授予 s3:GetDataAccess 和 s3:GetDataAccessGrantsInstanceForPrefix
权限以请求通过特定区域创建的 S3 访问权限实例的访问权限。这种设置使您能够以更加细粒度的方式管理 S3 访问,从而增强安全性。
接下来,我们将以分析工程师的身份在 EMR 上运行 Spark 作业,将一些示例数据转换为 Parquet 格式。请使用以下在
中提供的示例代码。下载该文件并将其拷贝到由
AWS CloudFormation 堆栈创建的 EMR_ARTIFACTS_BUCKET
。我们将使用具有 ReadWrite AWS IAM角色提交作业。请注意,针对 EMR 集群,我们已配置 S3 访问权限在访问未通过 S3 访问权限提供时回退到 IAM 角色。
`bash aws s3 cp converter.py s3://<EMR_ARTIFACTS_BUCKET>/code/ aws emr add- steps --cluster-id <EMR_CLUSTER_ID> \ --execution-role-arn <DATA_WRITER_ROLE> \ --steps '的 步骤 标签中查看作业的状态。
接下来,让我们登录 EMR Studio 并使用只读运行时角色的 EMR Serverless 应用分析场景1中的数据。首先,我们需要在 Serverless 应用上启用交互式端点。
删除)
删除)
接下来,在 Studio 中创建一个新的工作空间。
现在将工作空间连接到您的 EMR Serverless 应用。
删除)
让我们快速读取数据。
python df = spark.read.parquet(f"s3://{DATA_BUCKET}/output/weather-data/") df.createOrReplaceTempView("weather") df.show()
删除)
我们将执行一个简单的 COUNT(*)
:
python spark.sql("SELECT year, COUNT(*) FROM weather GROUP BY 1").show()
删除)
您还可以看到,如果尝试将数据写入输出位置,则会出现 Amazon S3 错误。
pythondf.write.format("csv").mode("overwrite").save("s3://<DATA_BUCKET>/output/weather- data-2/")
删除)
尽管您也可以通过 AWS IAM 策略授予类似的访问权限,但 Amazon S3 访问权限在那些已经无法通过 IAM 管理访问的组织中非常有用,或希望将 S3 访问权限映射到 IAM 身份中心的主体或角色,或此前使用过 EMR 文件系统 (EMRFS) 角色映射的情况。S3访问权限凭证也是临时的,提供了更安全的数据访问。此外,如下所示,跨账户访问也能从 S3 访问权限的简化中受益。
另一个常见的访问模式是跨账户访问数据。在数据网格逐渐兴起的情况下,数据生产者和消费者在不同的 AWS 账户中去中心化,这种模式变得越来越普遍。
此前,跨账户访问需要在配置 Spark 作业时设置复杂的跨账户假设角色操作和自定义凭证提供程序。借助 S3 访问权限,我们只需执行以下操作:
就这么简单!如果您手头有第二个账户,可以在数据消费者账户中部署 ,以创建新的 EMRServerless 应用和作业角色。如果没有,您可以按照下面的步骤进行操作。AWS CloudFormation堆栈的创建应在一分钟内完成。接下来,我们将为数据消费者授予对数据生成者账户中 S3 访问权限实例的访问权限。
<DATA_PRODUCER_ACCOUNT_ID>
和 <DATA_CONSUMER_ACCOUNT_ID>
替换为相关的 12 位 AWS 账户 ID。bash aws s3control put-access-grants-instance-resource-policy \ --account-id <DATA_PRODUCER_ACCOUNT_ID> \ --region us-east-2 \ --policy '{ "Version": "2012-10-17", "Id": "S3AccessGrantsPolicy", "Statement": [ { "Sid": "AllowAccessToS3AccessGrants", "Principal": { "AWS": "<DATA_CONSUMER_ACCOUNT_ID>" }, "Effect": "Allow", "Action": [ "s3:ListAccessGrants", "s3:ListAccessGrantsLocations", "s3:GetDataAccess", "s3:GetAccessGrantsInstanceForPrefix" ], "Resource": "arn:aws:s3:us- east-2:<DATA_PRODUCER_ACCOUNT_ID>:access-grants/default" } ] }'
bash aws s3control create-access-grant \ --account-id <DATA_PRODUCER_ACCOUNT_ID> \ --access-grants-location-id <LOCATION_ID_FROM_PREVIOUS_COMMAND> \ --access-grants-location-configurationS3SubPrefix="output/*" \ --permission READ \ --granteeGranteeType=IAM,GranteeIdentifier=DATA_CONSUMER_JOB_ROLE \ --region us-east-2
完成这些操作后,我们将能够从数据生成者账户的存储桶中在数据消费者账户中读取数据。我们只需再次运行简单的 COUNT(*)
查询。将
<APPLICATION_ID>
、<DATA_CONSUMER_JOB_ROLE>
和 <DATA_CONSUMER_LOG_BUCKET>
替换为第二个账户的 AWS CloudFormation 堆栈输出标签中的值,并将 <DATA_PRODUCER_BUCKET>
替换为第一个
Leave a Reply