我们如何使用 serverless.yml 创建 AWS S3 存储桶并向其中添加文件?
Posted
技术标签:
【中文标题】我们如何使用 serverless.yml 创建 AWS S3 存储桶并向其中添加文件?【英文标题】:How can we use serverless.yml to create an AWS S3 bucket and add a file to it? 【发布时间】:2017-05-25 03:26:57 【问题描述】:我想知道在 serverless-framework 的部署过程中是否可以利用serverless.yml
创建一个存储桶并添加一个特定的文件。
到目前为止,我已经能够添加创建存储桶的 S3 资源,但不确定如何添加特定文件。
resources:
Resources:
UploadBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: $self:custom.s3.bucket
AccessControl: Private
CorsConfiguration:
CorsRules:
- AllowedMethods:
- GET
- PUT
- POST
- HEAD
AllowedOrigins:
- "*"
AllowedHeaders:
- "*"
不确定是否可行,或者不确定如何利用 serverless.yml
在部署过程中上传默认文件(如果尚不存在)。
【问题讨论】:
【参考方案1】:没有官方的 AWS CloudFormation 资源可以管理(添加/删除)存储桶中的单个 S3 对象,但您可以使用 Custom Resource 创建一个使用 Lambda 函数调用 PUT Object
/@987654323 的资源@ 使用适用于 NodeJS 的 AWS 开发工具包的 API。
这是一个完整的 CloudFormation 模板示例:
Description: Create an S3 Object using a Custom Resource.
Parameters:
BucketName:
Description: S3 Bucket Name (must not already exist)
Type: String
Key:
Description: S3 Object Key
Type: String
Body:
Description: S3 Object Body
Type: String
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
S3Object:
Type: Custom::S3Object
Properties:
ServiceToken: !GetAtt S3ObjectFunction.Arn
Bucket: !Ref Bucket
Key: !Ref Key
Body: !Ref Body
S3ObjectFunction:
Type: AWS::Lambda::Function
Properties:
Description: S3 Object Custom Resource
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !Sub |
var response = require('cfn-response');
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
exports.handler = function(event, context)
var respond = (e) => response.send(event, context, e ? response.FAILED : response.SUCCESS, e ? e : );
var params = event.ResourceProperties;
delete params.ServiceToken;
if (event.RequestType == 'Create' || event.RequestType == 'Update')
s3.putObject(params).promise()
.then((data)=>respond())
.catch((e)=>respond(e));
else if (event.RequestType == 'Delete')
delete params.Body;
s3.deleteObject(params).promise()
.then((data)=>respond())
.catch((e)=>respond(e));
else
respond(Error: 'Invalid request type');
;
Timeout: 30
Runtime: nodejs4.3
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: Service: [lambda.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
Policies:
- PolicyName: S3Policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 's3:PutObject'
- 'S3:DeleteObject'
Resource: !Sub "arn:aws:s3:::$BucketName/$Key"
您还应该能够在 serverless.yml
配置文件中使用这些资源,尽管我对 Serverless 与 CloudFormation 资源/参数的集成方式并不肯定。
【讨论】:
对于真实案例的使用,请参阅serverless-stack.com/chapters/configure-s3-in-serverless.html 使用 SLSF 模板【参考方案2】:您是否查看过serverless-s3-sync 插件。作为部署的一部分,它允许您将文件夹从本地计算机上传到 S3。
plugins:
- serverless-s3-sync
custom:
s3Sync:
- bucketName: $self:custom.s3.bucket # required
bucketPrefix: assets/ # optional
localDir: dist/assets # required
【讨论】:
【参考方案3】:如果您这样做是为了部署网站,您可以使用serverless-finch,如果存储桶不存在,它会自动为您创建。
【讨论】:
以上是关于我们如何使用 serverless.yml 创建 AWS S3 存储桶并向其中添加文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 yaml 格式文件在 serverless.yml 中编写嵌套 IF,同时将其用于云形成?
在 CloudFormation 或 serverless.yml 中提供 OriginAccessIdentity 参考
cloudFormation 模板验证错误:如何拆分 serverless.yml 文件