web-dev-qa-db-fra.com

Comment pouvons-nous utiliser serverless.yml pour créer un compartiment AWS S3 et y ajouter un fichier?

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à.

11

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:

Launch Stack

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.

7
wjordan

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
1
Sam Williams

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à.

0
Vivek Maharajh