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:
Published on Java Code Geeks with permission by Mark Needham, partner at our JCG program. See the original article here: Serverless: S3 – S3BucketPermissions – Action does not apply to any resource(s) in statement Opinions expressed by Java Code Geeks contributors are their own. |