Serverless: S3 - S3BucketPermissions - Action does not apply to any resource(s) in statement
I’ve been playing around with S3 buckets with Serverless, and recently wrote the following code to create an S3 bucket and put a file into that bucket:
const AWS = require("aws-sdk");
let regionParams = { 'region': 'us-east-1' }
let s3 = new AWS.S3(regionParams);
let s3BucketName = "marks-blog-bucket";
console.log("Creating bucket: " + s3BucketName);
let bucketParams = { Bucket: s3BucketName, ACL: "public-read" };
s3.createBucket(bucketParams).promise()
.then(console.log)
.catch(console.error);
var putObjectParams = {
Body: "<html><body><h1>Hello blog!</h1></body></html>",
Bucket: s3BucketName,
Key: "blog.html"
};
s3.putObject(putObjectParams).promise()
.then(console.log)
.catch(console.error);
When I tried to cURL the file I got a permission denied exception:
$ curl --head --silent https://s3.amazonaws.com/marks-blog-bucket/blog.html
HTTP/1.1 403 Forbidden
x-amz-request-id: 512FE36798C0BE4D
x-amz-id-2: O1ELGMJ0jjs11WCrNiVNF2z2ssRgtO4+M4H2QQB5025HjIpC54VId0eKZryYeBYN8Pvb8GsolTQ=
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Fri, 29 Sep 2017 05:42:03 GMT
Server: AmazonS3
I wrote the following code to try and have Serverless create a bucket policy that would make all files in my bucket publicly accessible:
serverless.yml
service: marks-blog
frameworkVersion: ">=1.2.0 <2.0.0"
provider:
name: aws
runtime: python3.6
timeout: 180
resources:
Resources:
S3BucketPermissions:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: marks-blog-bucket
PolicyDocument:
Statement:
- Principal: "*"
Action:
- s3:GetObject
Effect: Allow
Sid: "AddPerm"
Resource: arn:aws:s3:::marks-blog-bucket
...
Let’s try to deploy it:
./node_modules/serverless/bin/serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (1.3 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
........
Serverless: Operation failed!
Serverless Error ---------------------------------------
An error occurred: S3BucketPermissions - Action does not apply to any resource(s) in statement.
D’oh! That didn’t do what I expected.
I learnt that this message means:
Some services do not let you specify actions for individual resources; instead, any actions that you list in the Action or NotAction element apply to all resources in that service. In these cases, you use the wildcard * in the Resource element.
To fix it we need to use the wildcard * to indicate that the s3:GetObject permission should apply to all values in the bucket rather than to the bucket itself.
Take 2!
serverless.yml
service: marks-blog
frameworkVersion: ">=1.2.0 <2.0.0"
provider:
name: aws
runtime: python3.6
timeout: 180
resources:
Resources:
S3BucketPermissions:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: marks-blog-bucket
PolicyDocument:
Statement:
- Principal: "*"
Action:
- s3:GetObject
Effect: Allow
Sid: "AddPerm"
Resource: arn:aws:s3:::marks-blog-bucket/*
...
Let’s deploy again and try to access the file:
$ curl --head --silent https://s3.amazonaws.com/marks-blog-bucket/blog.html
HTTP/1.1 200 OK
x-amz-id-2: uGwsLLoFHf+slXADGYkqW0bLfQ7EPG/kqzV3l2k7SMex4NlMEpNsNN/cIC9INLPohDtVFwUAa90=
x-amz-request-id: 7869E21760CD50F1
Date: Fri, 29 Sep 2017 06:05:11 GMT
Last-Modified: Fri, 29 Sep 2017 06:01:33 GMT
ETag: "57bac87219812c2f9a581943da34cfde"
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Length: 46
Server: AmazonS3
Success! And if we check in the AWS console we can see that the bucket policy has been applied to our bucket:
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.