I'm facing Access Denied for Multipart Upload into SSE-KMS encrypted bucket.
Code is running Glue (might be from other services, have no ability to verify). I’ve tried set of different permissions, even full access, no effect.
- Access for KMS is granted properly (
kms:Decrypt,kms:Encryptandkms:GenerateDataKey*) and it worked previously! - This issues appears for both Glue on Spark and Glue PyShell jobs and do not affect small files.
- For Glue PySpark jobs this issue appear
only when
Glue security configurationis set (the key is same as granted for the job) - For PySpark, writing is done via
output_sink = glueContext.getSink(...) output_sink.writeFrame(dynamic_frame) - For PySpark, writing is done via
df = pandas.read_excel(...) df.to_parquet(output_file_path, compression="snappy", index=False) - There are no bucket policies applied at all except restricting public access
What I already tried with no success:
- Add
s3:*permissions to resources - Add
kms:*permissions to the policy for KMS key used in the jobs - Additionally add bucket ARN resources (without key prefixes)
- Setting
s3:*+Resource: "*" - Add
glue.amazonaws.comto Principal Services for KMS key - For PySpark job, specified manually
fs.s3.enableServerSideEncryptionandfs.s3.serverSideEncryption.kms.keyIdwith corresponding key ARN - For PyShell job, tried upgrading
awscli,botocoreandboto3versions (pandas=1.1.5ands3fs=0.4.2versions cannot be upgraded to higher versions due to PyShell python version of3.6.13)
Part of the stacktrace for PySpark job indicating multipart upload issue:
: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 1.0 failed 4 times, most recent failure: Lost task 0.3 in stage 1.0 (TID 4, 172.36.10.82, 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: ..; S3 Extended Request ID: ..), S3 Extended Request ID: ....
..<cropped entries>..
at com.amazon.ws.emr.hadoop.fs.s3.lite.executor.GlobalS3Executor.execute(GlobalS3Executor.java:110)
at com.amazon.ws.emr.hadoop.fs.s3.lite.AmazonS3LiteClient.invoke(AmazonS3LiteClient.java:189)
at com.amazon.ws.emr.hadoop.fs.s3.lite.AmazonS3LiteClient.invoke(AmazonS3LiteClient.java:184)
at com.amazon.ws.emr.hadoop.fs.s3.lite.AmazonS3LiteClient.putObject(AmazonS3LiteClient.java:107)
at com.amazon.ws.emr.hadoop.fs.s3n.Jets3tNativeFileSystemStore.storeFile(Jets3tNativeFileSystemStore.java:174)
at com.amazon.ws.emr.hadoop.fs.s3n.MultipartUploadOutputStream.uploadSinglePart(MultipartUploadOutputStream.java:208)
at com.amazon.ws.emr.hadoop.fs.s3n.MultipartUploadOutputStream.close(MultipartUploadOutputStream.java:423)
at org.apache.hadoop.fs.FSDataOutputStream$PositionCache.close(FSDataOutputStream.java:74)
at org.apache.hadoop.fs.FSDataOutputStream.close(FSDataOutputStream.java:108)
at org.apache.parquet.nimble.hadoop.ParquetFileWriter.end(ParquetFileWriter.java:579)
..<cropped entries>..
at com.amazonaws.services.glue.sinks.GlueParquetHadoopWriter.writeParquetPartitioned(GlueParquetHadoopWriter.scala:163)
at com.amazonaws.services.glue.sinks.GlueParquetHadoopWriter$$anonfun$doParquetWrite$2.apply(GlueParquetHadoopWriter.scala:188)
at com.amazonaws.services.glue.sinks.GlueParquetHadoopWriter$$anonfun$doParquetWrite$2.apply(GlueParquetHadoopWriter.scala:181)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
at org.apache.spark.scheduler.Task.run(Task.scala:121)
..<cropped entries>..
Error message for PyShell:
Sending http request: <AWSPreparedRequest stream_output=False, method=PUT,
url=https://my-bucket-name.s3.ca-central-1.amazonaws.com/folder/folder/folder/file-name.snappy.parquet?partNumber=1&uploadId=~uploadId~,
headers={
'User-Agent': b'Botocore/1.12.232 Python/3.6.13 Linux/4.14.238-125.422.amzn1.x86_64',
'Content-MD5': b'Ic4VG7BgETssQJOhSK+E/Q==',
'Expect': b'100-continue',
'X-Amz-Date': b'20220518T163248Z',
'X-Amz-Security-Token': b'~token-data~',
'X-Amz-Content-SHA256': b'UNSIGNED-PAYLOAD',
'Authorization': b'AWS4-HMAC-SHA256 Credential=~credential~, SignedHeaders=content-md5;host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=~signature~',
'Content-Length': '5421349'
}>
...
Traceback (most recent call last):
File "/tmp/glue-python-scripts-2tscdixy/script.py", line 44, in main
df.to_parquet(output_file_path, compression="snappy", index=False)
File "/glue/lib/installation/pandas/util/_decorators.py", line 199, in wrapper
return func(*args, **kwargs)
File "/glue/lib/installation/pandas/core/frame.py", line 2372, in to_parquet
**kwargs,
File "/glue/lib/installation/pandas/io/parquet.py", line 276, in to_parquet
**kwargs,
File "/glue/lib/installation/pandas/io/parquet.py", line 123, in write
self.api.parquet.write_table(table, path, compression=compression, **kwargs)
File "/glue/lib/installation/pyarrow/parquet.py", line 2034, in write_table
writer.write_table(table, row_group_size=row_group_size)
File "/glue/lib/installation/pyarrow/parquet.py", line 686, in __exit__
self.close()
File "/glue/lib/installation/pyarrow/parquet.py", line 710, in close
self.file_handle.close()
File "pyarrow/io.pxi", line 173, in pyarrow.lib.NativeFile.close
File "/glue/lib/installation/fsspec/spec.py", line 1630, in close
self.flush(force=True)
File "/glue/lib/installation/fsspec/spec.py", line 1501, in flush
if self._upload_chunk(final=force) is not False:
File "/glue/lib/installation/s3fs/core.py", line 1245, in _upload_chunk
raise IOError('Write failed: %r' % exc)
OSError: Write failed: ClientError('An error occurred (AccessDenied) when calling the UploadPart operation: Access Denied',)