【问题标题】:AWS Glue job to pull the data from DynamoDB in another account用于从另一个账户中的 DynamoDB 提取数据的 AWS Glue 作业
【发布时间】:2020-07-02 11:06:21
【问题描述】:

我正在使用 AWS Glue 将数据从 DynamoDB 复制到 S3。我已经编写了以下代码以将 DyanmoDB 表复制到同一帐户中的 S3。它工作正常,用 6 亿条记录复制我的表,没有任何问题。大约需要20分钟。

from pyspark.context import SparkContext
from awsglue.context import GlueContext
from datetime import datetime

# inputs
dataset_date = datetime.strftime(datetime.now(), '%Y%m%d')
table_name = "table-name"
read_percentage = "0.5"
output_location = 's3://'+dataset_date
fmt ="json" 

# glue setup
sc = SparkContext()
glueContext = GlueContext(sc)

# scan the DDB table
table = glueContext.create_dynamic_frame.from_options("dynamodb",
                                                  connection_options={
                                                                      "dynamodb.input.tableName": table_name,
                                                                      "dynamodb.throughput.read.percent": read_percentage,
                                                                      "dynamodb.splits": "100"
                                                                      }
                                                )

# write to S3
glueContext.write_dynamic_frame.from_options(frame=table,
                                         connection_type="s3",
                                         connection_options={"path": output_location},
                                         format=fmt,
                                         transformation_ctx="datasink"
                                        )

但现在我想使用上述脚本进行跨账户 S3 转储。 DynamoDB 表位于账户 A(prod 账户)中,用于从 DynamoDB 表和 S3 存储桶中读取数据以转储该数据的 Glue 作业位于账户 B(DW 账户)中。我不知道是否可以使用我的脚本,但提供跨账户 Glue 访问权限,以便它可以从账户 A 读取 DynamoDB 表

【问题讨论】:

    标签: amazon-web-services amazon-s3 amazon-dynamodb aws-glue


    【解决方案1】:

    在账户 A(DynamoDB 表所有者账户)中创建一个 IAM 角色,允许 Glue 作为 Principal 读取表。

    为账户 A(DynamoDB 表所有者账户)中的 IAM 角色配置允许读取表中数据的权限策略。您可以从中构建的示例如下所示:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "ListAndDescribe",
                "Effect": "Allow",
                "Action": [
                    "dynamodb:List*",
                    "dynamodb:DescribeReservedCapacity*",
                    "dynamodb:DescribeLimits",
                    "dynamodb:DescribeTimeToLive"
                ],
                "Resource": "*"
            },
            {
                "Sid": "AllTables",
                "Effect": "Allow",
                "Action": [
                    "dynamodb:BatchGet*",
                    "dynamodb:DescribeStream",
                    "dynamodb:DescribeTable",
                    "dynamodb:Get*",
                    "dynamodb:Query",
                    "dynamodb:Scan"
                ],
                "Resource": [
                    "arn:aws:dynamodb:*:*:table/table-1",
                    "arn:aws:dynamodb:*:*:table/table-2"
                ]
            }
        ]
    }
    

    在账户 A(Dynamo 数据库表账户)的上述 IAM 角色中配置信任策略,以允许 Glue 代入它。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": "glue.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
    

    在为账户 B(不拥有表)中的 Glue 作业配置的 IAM 角色中, 包括一个权限策略,让它在账户 A(Dynamo DB 表所有者账户)中担任 IAM 角色。

        {
            "Sid": "DelegateDynamoDBTablesOwnerRoleArn",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::dynamo-db-table-owner-role-arn:role/*"
        }
    

    参考文献

    1. https://docs.aws.amazon.com/glue/latest/dg/cross-account-access.html#cross-account-calling-etl

    【讨论】:

    • 问题不在于存储桶策略。我试图访问帐户 B 中的 dynamodb 表,而我的 Glue 作业和 S3 目标位于帐户 A 中
    • 我的错,我会修改我的答案以反映这种理解。
    • @LisaMathew 需要你的帮助!我正在尝试使用您在此处发布的代码从 dynamo db 表中读取数据。我的 Jupyter notebook 运行以下 2 行后出现错误。 sc = SparkContext() 胶水上下文 = GlueContext(sc)。遇到错误:无法同时运行多个 SparkContexts; init 在 /mnt/yarn/usercache/livy/appcache/application_1602527659009_0010/container_1602527659009_0010_01_000001/tmp/7416680492502689723:589span 创建的现有 SparkContext(app=livy-session-9, master=yarn)
    【解决方案2】:

    我认为这不适用于在 DW 帐户中运行的胶水脚本。

    GlueContext 使用表名连接到 DynamoDB:

    https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect.html#aws-glue-programming-etl-connect-dynamodb

    您应该探索的是在 Prod 帐户中运行胶水脚本并授予对 DW 存储桶的跨帐户访问权限,以便在 prod 帐户中运行的 Glue 可以承担编写目标 S3 的角色DW 帐户中的存储桶。

    【讨论】:

    • 我使用 GlueContext 配置设置conf=SparkConf() glueContext = GlueContext(SparkContext.getOrCreate(conf)) spark=glueContext.spark_session sc=spark.sparkContext glueContext._jsc.hadoopConfiguration().set("dynamodb.awsAccessKeyId", "xvczxcvzcvzcxvxzcv") glueContext._jsc.hadoopConfiguration().set("dynamodb.awsSecretAccessKey", "xcvzcvzxcvzcvxzc+EBDFc2L0F")
    • 让我告诉你一些奇怪的事情。这项工作正在发挥作用,这是完美的。我对永久凭据而不是临时会话令牌有点不安。我很确定这并不容易,因为glueContext._jsc.hadoopConfiguration().set("dynamodb.awsSessionToken", "<token>") probably won't work. 我想知道如何在从 DynamoDB 读取的 aws 粘合作业中通过临时 STS 会话更进一步,它不会受到伤害。
    • 是的,@starpebble。我同意你的看法。我认为亚马逊会更改 GlueContext 以支持角色而不是凭据。根据实现,可以调用 sts 假设角色并获取临时凭证。但这确实不是最好的体验。
    • 是的。 @AndersonMarques,有点像 AWS Glue 中的很多间接性。 Hadoop 和 Spark 有漂亮的凭据提供程序类。 boto3 也有点支持 STS 令牌。 AWS Glue 上下文有点碍事。
    猜你喜欢
    • 1970-01-01
    • 2022-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多