web-dev-qa-db-fra.com

Ajouter des données à un objet S3

Supposons que je souhaite écrire sur une machine dans un certain fichier journal stocké sur un compartiment S3.

Ainsi, la machine doit avoir des capacités d'écriture dans ce compartiment, mais je ne veux pas qu'elle puisse écraser ou supprimer des fichiers de ce compartiment (y compris celui sur lequel je veux écrire).

En résumé, je souhaite que ma machine puisse uniquement ajouter des données à ce fichier journal, sans les remplacer ni les télécharger.

Existe-t-il un moyen de configurer mon S3 pour fonctionner de la sorte? Peut-être y a-t-il une politique IAM que je peux y attacher pour que cela fonctionne comme je le souhaite?

63
Theodore

Malheureusement, vous ne pouvez pas.

S3 n'a pas d'opération "ajouter".* Une fois qu'un objet a été téléchargé, il n'y a aucun moyen de le modifier sur place; votre seule option est de télécharger un nouvel objet pour le remplacer, ce qui ne répond pas à vos exigences.

*: Oui, je sais que ce post a deux ans. C'est toujours précis, cependant.

97
duskwuff

Comme le dit la réponse acceptée, vous ne pouvez pas. La meilleure solution que je connaisse consiste à utiliser:

AWS Kinesis Firehose

https://aws.Amazon.com/kinesis/firehose/

Leur exemple de code a l'air compliqué, mais le vôtre peut être très simple. Vous continuez à effectuer des opérations PUT (ou BATCH PUT) sur un flux de livraison Kinesis Firehose dans votre application (à l'aide du kit AWS SDK), et vous configurez le flux de livraison Kinesis Firehose pour envoyer vos données livrées à un compartiment AWS S3 de votre choix (dans la Console AWS Kinesis Firehose).

enter image description here

Ce n'est toujours pas aussi pratique que >> depuis la ligne de commande Linux, car une fois que vous avez créé un fichier sur S3, vous devez à nouveau gérer le téléchargement, l'ajout et le téléchargement du nouveau fichier, mais vous ne devez le faire qu'une seule fois. par lot de lignes plutôt que pour chaque ligne de données, vous n'avez donc pas à vous soucier des charges énormes dues au volume d'opérations d'ajout. Peut-être que cela peut être fait mais je ne vois pas comment le faire depuis la console.

10
Sridhar Sarnobat

Les objets sur S3 ne sont pas annexables. Vous avez 2 solutions dans ce cas:

  1. copier toutes les données S3 dans un nouvel objet, ajouter le nouveau contenu et réécrire dans S3.
function writeToS3(input) {
    var content;
    var getParams = {
        Bucket: 'myBucket', 
        Key: "myKey"
    };

    s3.getObject(getParams, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
            content = new Buffer(data.Body).toString("utf8");
            content = content + '\n' + new Date() + '\t' + input;
            var putParams = {
                Body: content,
                Bucket: 'myBucket', 
                Key: "myKey",
                ACL: "public-read"
             };

            s3.putObject(putParams, function(err, data) {
                if (err) console.log(err, err.stack); // an error occurred
                else     {
                    console.log(data);           // successful response
                }
             });
        }
    });  
}
  1. La deuxième option consiste à utiliser Kinesis Firehose. C'est assez simple. Vous devez créer votre flux de livraison firehose et lier la destination au compartiment S3. C'est ça!
function writeToS3(input) {
    var content = "\n" + new Date() + "\t" + input;
    var params = {
      DeliveryStreamName: 'myDeliveryStream', /* required */
      Record: { /* required */
        Data: new Buffer(content) || 'STRING_VALUE' /* Strings will be Base-64 encoded on your behalf */ /* required */
      }
    };

    firehose.putRecord(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     console.log(data);           // successful response
    }); 
}
4
Bharthan

Comme d'autres l'ont déjà indiqué, les objets S3 ne peuvent pas être ajoutés.
Cependant, une autre solution consisterait à écrire dans les journaux CloudWatch puis à exporter les journaux que vous voulez au format S . Cela empêcherait également les attaquants accédant à votre serveur de supprimer de votre compartiment S3, car Lambda ne nécessiterait aucune autorisation S3.

0
Leo Glowacki

J'ai eu le même problème et voici ce que j'avais demandé

comment ajouter des données dans un fichier avec AWS Lambda

Voici ce que je propose pour résoudre le problème ci-dessus:

Utilisez getObject pour revenir du fichier existant

   s3.getObject(getParams, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else{
       console.log(data);           // successful response
       var s3Projects = JSON.parse(data.Body);
       console.log('s3 data==>', s3Projects);
       if(s3Projects.length > 0) {
           projects = s3Projects;
       }   
   }
   projects.Push(event);
   writeToS3(); // Calling function to append the data
});

Fonction d'écriture à ajouter au fichier

   function writeToS3() {
    var putParams = {
      Body: JSON.stringify(projects),
      Bucket: bucketPath, 
      Key: "projects.json",
      ACL: "public-read"
     };

    s3.putObject(putParams, function(err, data) {
       if (err) console.log(err, err.stack); // an error occurred
       else     console.log(data);           // successful response
        callback(null, 'Hello from Lambda');
     });
}

J'espère que cette aide !!

0
Neeraj Kumar