CloudFormation创建的AWS Glue Job写入S3时出现Access Denied错误
结合我遇到过的类似场景,你这个问题的核心矛盾点在于CloudFormation部署的任务和手动创建的任务权限表现不一致——看起来权限都给全了,但实际还是被拒,大概率是CloudFormation模板里的某个配置细节没对齐手动任务的设置,以下是几个最可能的遗漏点:
1. 检查IAM服务角色的信任策略是否正确
手动创建Glue服务角色时,AWS会自动生成包含glue.amazonaws.com的信任关系,但如果是CloudFormation自定义角色,很容易在信任策略上出错:
- 要么是没添加
glue.amazonaws.com作为信任实体; - 要么是加了不必要的条件限制(比如
aws:SourceArn或aws:SourceAccount配置错误),导致Glue服务无法Assume这个角色。
正确的信任策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "glue.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
另外还要检查是否有**SCP(服务控制策略)**限制了这个角色的sts:AssumeRole操作,SCP的优先级高于IAM策略,会直接导致权限被拒。
2. 确认Glue任务的S3路径配置无错误
CloudFormation中如果用参数、Sub函数拼接S3路径,很容易出现变量未解析、多余斜杠或空格的问题,导致实际访问的S3路径和手动任务的路径不一致。比如:
- 错误写法:
!Sub "s3://${BucketName}data/"(少了斜杠) - 正确写法:
!Sub "s3://${BucketName}/data/"
建议直接对比手动任务的S3路径和CloudFormation生成的任务路径,确保完全一致。
3. 验证Glue任务是否正确关联了目标IAM角色
检查CloudFormation模板中Glue Job的Role属性,是否准确引用了你创建的IAM角色ARN。很多时候会因为角色名称写错、账号ID填错,导致任务关联了错误的角色(甚至默认角色),自然没有访问S3的权限。
正确的CloudFormation配置示例(YAML):
MyGlueETLJob: Type: AWS::Glue::Job Properties: Role: !GetAtt MyGlueServiceRole.Arn Command: Name: glueetl ScriptLocation: s3://my-glue-scripts/etl-job.py # 其他任务配置...
4. 检查S3桶的桶策略是否存在拒绝规则
虽然你给了IAM角色AmazonS3FullAccess,但如果S3桶本身配置了桶策略,其中的Deny语句会覆盖IAM的允许权限。比如桶策略可能明确拒绝了CloudFormation创建的角色,或者设置了只允许特定IP、特定角色访问的条件。
重点排查桶策略中是否有针对你的Glue角色的Deny语句,比如:
{ "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::123456789012:role/CloudFormation-Glue-Role" }, "Action": "s3:*", "Resource": ["arn:aws:s3:::my-target-bucket/*", "arn:aws:s3:::my-target-bucket"] }
5. 排除IAM权限延迟问题
IAM策略和角色的生效有时候会有1-2分钟的延迟,如果你刚部署完CloudFormation就立刻运行任务,可能会遇到权限未生效的情况。可以尝试等待几分钟后重新运行任务,或者手动重新附加一次IAM策略触发刷新。
完整错误日志:
"/mnt/yarn/usercache/root/appcache/application_1...5_0002/container_15...45_0002_01_000001/py4j-0.10.4-src.zip/py4j/protocol.py", line 319, in get_return_value py4j.protocol.Py4JJavaError: An error occurred while calling o145.pyWriteDynamicFrame. : org.apache.spark.SparkException: Job aborted due to stage failure: Task 3 in stage 2.0 failed 4 times, most recent failure: Lost task 3.3 in stage 2.0 (TID 30, ip-10-....us-west-2.compute.internal, executor 1): com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: F...49), S3 Extended Request ID: eo...wXZw= at com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
内容的提问来源于stack exchange,提问作者ky2ninh

