Update: Found the answer, thanks.
I'm setting up a lambda that periodically fetches some data, does some processing and saves a file to s3.
This is the function:
exports.handler = async function(event, context) {
const data = await fetchXlsx();
const uploaded = s3.putObject({
Bucket: 'my-bucket',
Key: 'current.json',
ACL: 'public-read', // Works fine without this line
ContentType: 'application/json',
Body: JSON.stringify(data)
}).promise()
return uploaded
}
And this is the policy attached to the execution role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
The code above works fine if I comment out the ACL
property, but then the file isn't public, and I need it to be so.
Running the code as it is, it throws Access Denied:
{
"errorType": "AccessDenied",
"errorMessage": "Access Denied",
"trace": [
"AccessDenied: Access Denied",
" at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:831:35)",
" at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)",
" at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)",
" at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)",
" at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)",
" at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)",
" at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10",
" at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)",
" at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)",
" at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"
]
}
I've tried setting up the policy in many different ways, including trying to make it as permissible as possible:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": "*"
}
]
}
But that didn't work.
On the bucket side, I haven't found any settings to mess with other than setting Block all public access
to off but that didn't help either.
TLDR; I can upload a file from Lambda to S3, but how can I make it public?