我一直在使用Serverless来玩S3存储桶,最近编写了以下代码来创建S3存储桶并将文件放入该存储桶:
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);
当我尝试卷曲文件时,出现权限被拒绝的异常:
$ 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
我编写了以下代码,以尝试让无服务器创建存储桶策略,以使存储桶中的所有文件可公开访问:
无服务器
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
...
让我们尝试部署它:
./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.
天哪! 那没有达到我的预期。
我了解到此消息的意思是 :
某些服务不允许您为单个资源指定操作; 相反,您在Action或NotAction元素中列出的所有操作都将应用于该服务中的所有资源。 在这些情况下,请在Resource元素中使用通配符*。
要解决此问题,我们需要使用通配符*来指示s3:GetObject权限应应用于存储桶中的所有值,而不是存储桶本身。
拿2!
无服务器
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/*
...
让我们再次部署并尝试访问该文件:
$ 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
成功! 而且,如果我们在AWS控制台中签入,则可以看到存储桶策略已应用于我们的存储桶: