运行AWS Glue Studio ETL脚本时出现ARN角色授权错误
问题背景
运行AWS Glue Studio脚本执行数据关联、字段重命名操作,连接器和目标端均为通过AWS Glue Catalog对接的Redshift。最初报错提示IAM未添加到Redshift,完成添加操作后出现新的权限报错,错误堆栈如下:
py4j.protocol.Py4JJavaError: An error occurred while calling o85.getDynamicFrame. : java.sql.SQLException: Exception thrown in awaitResult: at com.databricks.spark.redshift.JDBCWrapper.com$databricks$spark$redshift$JDBCWrapper$$executeInterruptibly(RedshiftJDBCWrapper.scala:133) at com.databricks.spark.redshift.JDBCWrapper.executeInterruptibly(RedshiftJDBCWrapper.scala:109) at com.databricks.spark.redshift.RedshiftRelation.buildScan(RedshiftRelation.scala:138) at org.apache.spark.sql.execution.datasources.DataSourceStrategy$$anonfun$10.apply(DataSourceStrategy.scala:293) at org.apache.spark.sql.execution.datasources.DataSourceStrategy$$anonfun$10.apply(DataSourceStrategy.scala:293) at org.apache.spark.sql.execution.datasources.DataSourceStrategy$$anonfun$pruneFilterProject$1.apply(DataSourceStrategy.scala:326) at org.apache.spark.sql.execution.datasources.DataSourceStrategy$$anonfun$pruneFilterProject$1.apply(DataSourceStrategy.scala:325) at org.apache.spark.sql.execution.datasources.DataSourceStrategy.pruneFilterProjectRaw(DataSourceStrategy.scala:381) at org.apache.spark.sql.execution.datasources.DataSourceStrategy.pruneFilterProject(DataSourceStrategy.scala:321) at org.apache.spark.sql.execution.datasources.DataSourceStrategy.apply(DataSourceStrategy.scala:289) at org.apache.spark.sql.catalyst.planning.QueryPlanner$$anonfun$1.apply(QueryPlanner.scala:63) at org.apache.spark.sql.catalyst.planning.QueryPlanner$$anonfun$1.apply(QueryPlanner.scala:63) at scala.collection.Iterator$$anon$12.nextCur(Iterator.scala:435) at scala.collection.Iterator$$anon$12.hasNext(Iterator.scala:441) at scala.collection.Iterator$$anon$12.hasNext(Iterator.scala:440) at org.apache.spark.sql.catalyst.planning.QueryPlanner.plan(QueryPlanner.scala:93) at org.apache.spark.sql.catalyst.planning.QueryPlanner$$anonfun$2$$anonfun$apply$2.apply(QueryPlanner.scala:78) at org.apache.spark.sql.catalyst.planning.QueryPlanner$$anonfun$2$$anonfun$apply$2.apply(QueryPlanner.scala:75) at scala.collection.TraversableOnce$$anonfun$foldLeft$1.apply(TraversableOnce.scala:157) at scala.collection.TraversableOnce$$anonfun$foldLeft$1.apply(TraversableOnce.scala:157) at scala.collection.Iterator$class.foreach(Iterator.scala:891) at scala.collection.AbstractIterator.foreach(Iterator.scala:1334) at scala.collection.TraversableOnce$class.foldLeft(TraversableOnce.scala:157) at scala.collection.AbstractIterator.foldLeft(Iterator.scala:1334) at org.apache.spark.sql.catalyst.planning.QueryPlanner$$anonfun$2.apply(QueryPlanner.scala:75) at org.apache.spark.sql.catalyst.planning.QueryPlanner$$anonfun$2.apply(QueryPlanner.scala:67) at scala.collection.Iterator$$anon$12.nextCur(Iterator.scala:435) at scala.collection.Iterator$$anon$12.hasNext(Iterator.scala:441) at org.apache.spark.sql.catalyst.planning.QueryPlanner.plan(QueryPlanner.scala:93) at org.apache.spark.sql.execution.QueryExecution.sparkPlan$lzycompute(QueryExecution.scala:72) at org.apache.spark.sql.execution.QueryExecution.sparkPlan(QueryExecution.scala:68) at org.apache.spark.sql.execution.QueryExecution.executedPlan$lzycompute(QueryExecution.scala:77) at org.apache.spark.sql.execution.QueryExecution.executedPlan(QueryExecution.scala:77) at org.apache.spark.sql.Dataset.withAction(Dataset.scala:3359) at org.apache.spark.sql.Dataset.head(Dataset.scala:2544) at org.apache.spark.sql.Dataset.take(Dataset.scala:2758) at com.amazonaws.services.glue.JDBCDataSource.getLastRow(DataSource.scala:944) at com.amazonaws.services.glue.JDBCDataSource.getJdbcJobBookmark(DataSource.scala:805) at com.amazonaws.services.glue.JDBCDataSource.getDynamicFrame(DataSource.scala:829) at com.amazonaws.services.glue.DataSource$class.getDynamicFrame(DataSource.scala:94) at com.amazonaws.services.glue.SparkSQLDataSource.getDynamicFrame(DataSource.scala:658) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244) at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357) at py4j.Gateway.invoke(Gateway.java:282) at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132) at py4j.commands.CallCommand.execute(CallCommand.java:79) at py4j.GatewayConnection.run(GatewayConnection.java:238) at java.lang.Thread.run(Thread.java:748) Caused by: java.sql.SQLException: [Amazon](500310) Invalid operation: Not authorized to get credentials of role arn:aws:iam::**********:role/glue_etl_role Details: ----------------------------------------------- error: Not authorized to get credentials of role arn:aws:iam::*********:role/glue_etl_role code: 30000 context: query: 0 location: xen_aws_credentials_mgr.cpp:391 process: padbmaster
报错核心
无权限获取ARN为arn:aws:iam::********:role/glue_etl_role的角色凭证
排查及解决方案
- 检查IAM角色的信任策略:Redshift服务需要被授权代入该Glue角色才能获取凭证,需在
glue_etl_role的信任策略中添加Redshift服务作为信任主体,参考配置如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "glue.amazonaws.com", "redshift.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
- 检查Redshift集群关联角色配置:登录Redshift控制台进入对应集群的「属性」页,下拉到「集群权限」板块,确认
glue_etl_role已被关联到当前集群,且关联时未限制仅可用于特定功能。 - 检查Glue角色的权限配置:确认
glue_etl_role已附加Redshift读写权限、以及AWSGlueServiceRole托管策略,包含S3临时目录读写、Glue Catalog访问等必备权限。 - 检查Redshift数据库内用户权限:Glue任务对接Redshift使用的数据库用户,需要具备对应角色的ASSUMEROLE权限,执行如下SQL完成授权:
GRANT ASSUMEROLE ON ROLE "arn:aws:iam::**********:role/glue_etl_role" TO <Glue对接使用的Redshift数据库用户名>;
- 检查角色ARN配置一致性:确认Glue任务中填写的Redshift角色ARN、Redshift集群关联的角色ARN、报错中提示的角色ARN三者完全一致,不存在拼写错误、账号ID错误或角色名称错误。
内容的提问来源于stack exchange,提问作者Darshan B
相关产品推荐
相关产品推荐

