Je me demande s'il est possible de tirer parti de serverless.yml
pour créer un compartiment et y ajouter un fichier spécifique pendant le processus de déploiement de framework sans serveur.
Jusqu'à présent, j'ai pu ajouter la ressource S3 qui crée le compartiment, mais je ne sais pas comment ajouter un fichier spécifique.
resources:
Resources:
UploadBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.s3.bucket}
AccessControl: Private
CorsConfiguration:
CorsRules:
- AllowedMethods:
- GET
- PUT
- POST
- HEAD
AllowedOrigins:
- "*"
AllowedHeaders:
- "*"
Je ne sais pas si c'est possible, ni comment tirer parti du serverless.yml
pour télécharger un fichier par défaut pendant le processus de déploiement s'il n'est pas encore là.
Il n'y a pas de ressource AWS CloudFormation officielle qui gère (ajoute/supprime) un objet S3 individuel dans un compartiment, mais vous pouvez en créer un avec ressource personnalisée qui utilise une fonction Lambda pour appeler le PUT Object
/ DELETE Object
API utilisant le kit AWS SDK pour NodeJS.
Voici un exemple complet de modèle 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}"
Vous devriez également pouvoir utiliser ces ressources dans un serverless.yml
fichier de configuration, bien que je ne sois pas certain de la façon dont Serverless s'intègre exactement aux ressources/paramètres CloudFormation.
Avez-vous regardé le plugin serverless-s3-sync. Il vous permet de télécharger un dossier sur S3 depuis votre ordinateur local dans le cadre du déploiement.
plugins:
- serverless-s3-sync
custom:
s3Sync:
- bucketName: ${self:custom.s3.bucket} # required
bucketPrefix: assets/ # optional
localDir: dist/assets # required
Si vous faites cela pour déployer un site Web, vous pouvez utiliser serverless-finch et il créera automatiquement le compartiment pour vous s'il n'existe pas déjà.