[amazon-web-services] S3 객체에 데이터 추가

S3 버킷에 저장된 특정 로그 파일에 쓸 수있는 머신이 있다고 가정 해 보겠습니다.

따라서 머신에는 해당 버킷에 대한 쓰기 기능이 있어야하지만 해당 버킷 (내가 쓰려는 파일 포함)에있는 파일을 덮어 쓰거나 삭제할 수있는 기능이 필요하지 않습니다.

따라서 기본적으로 내 컴퓨터가 데이터를 재정의하거나 다운로드하지 않고 해당 로그 파일에만 데이터를 추가 할 수 있기를 바랍니다.

S3가 그렇게 작동하도록 구성하는 방법이 있습니까? 내가 원하는대로 작동하도록 연결할 수있는 IAM 정책이있을 수 있습니까?



답변

불행히도 할 수 없습니다.

S3에는 “추가”작업이 없습니다. * 객체가 업로드되면 제자리에서 수정할 수 없습니다. 유일한 옵션은 요구 사항을 충족하지 않는 새 개체를 업로드하여 대체하는 것입니다.

* : 예,이 게시물이 몇 년 전이라는 것을 알고 있습니다. 그래도 여전히 정확합니다.


답변

받아 들여진 대답에 따르면 할 수 없습니다. 내가 아는 가장 좋은 해결책은 다음을 사용하는 것입니다.

AWS Kinesis Firehose

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

그들의 코드 샘플 은 복잡해 보이지만 당신은 정말 간단 할 수 있습니다. 애플리케이션의 Kinesis Firehose 전송 스트림에 대해 계속 PUT (또는 BATCH PUT) 작업을 수행하고 (AWS SDK 사용), 스트리밍 데이터를 선택한 AWS S3 버킷으로 전송하도록 Kinesis Firehose 전송 스트림을 구성합니다 ( AWS Kinesis Firehose 콘솔).

여기에 이미지 설명 입력

>>S3에서 파일을 생성 한 후에는 새 파일을 다시 다운로드, 추가 및 업로드해야하지만 한 줄에 한 번만 수행하면되므로 여전히 Linux 명령 줄에서 만큼 편리하지 않습니다. 추가 작업의 양으로 인해 막대한 비용이 발생하는 것에 대해 걱정할 필요가 없습니다. 아마도 할 수 있지만 콘솔에서 어떻게하는지 볼 수 없습니다.


답변

S3의 객체는 추가 할 수 없습니다. 이 경우 두 가지 솔루션이 있습니다.

  1. 모든 S3 데이터를 새 객체에 복사하고 새 콘텐츠를 추가 한 다음 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. 두 번째 옵션은 Kinesis Firehose를 사용하는 것입니다. 이것은 매우 간단합니다. firehose 전송 스트림을 생성하고 대상을 S3 버킷에 연결해야합니다. 그게 다야!
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
    });
}


답변

다른 사람들이 이전에 언급했듯이 S3 객체는 추가 할 수 없습니다.
그러나 또 다른 해결책은 CloudWatch 로그에 기록한 다음 원하는 로그를 S3내보내는 것 입니다. 또한 Lambda에는 S3 권한이 필요하지 않기 때문에 서버에 액세스하는 공격자가 S3 버킷에서 삭제하는 것을 방지 할 수 있습니다.


답변

S3와 유사한 서비스를 사용하여 객체에 데이터를 추가하려는 경우 Alibaba Cloud OSS (Object Storage Service) 가이를 기본적으로 지원합니다 .

OSS는 AppendObject API를 통해 추가 업로드를 제공하므로 개체 끝에 콘텐츠를 직접 추가 할 수 있습니다. 이 메서드를 사용하여 업로드 한 개체는 추가 가능한 개체이고 다른 방법을 사용하여 업로드 한 개체는 일반 개체입니다. 추가 된 데이터는 즉시 읽을 수 있습니다.


답변

나는 비슷한 문제가 있었고 이것이 내가 요청한 것입니다.

AWS Lambda를 사용하여 파일에 데이터를 추가하는 방법

위의 문제를 해결하기 위해 내가 생각 해낸 것은 다음과 같습니다.

getObject를 사용하여 기존 파일에서 검색

   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
});

파일에 추가 할 쓰기 기능

   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');
     });
}

이 도움을 바랍니다 !!


답변