AWS S3

KangWook·2024년 9월 13일
0

S3 기본 개념

AWS S3는 객체 스토리지 서비스로, 데이터를 "버킷(bucket)"에 저장하는 방식입니다. 각 버킷은 사용자가 지정한 이름과 권한을 가지며, 내부에 저장된 데이터는 객체(object)로 관리됩니다. S3는 확장성, 보안, 높은 가용성을 제공하여 다양한 애플리케이션에서 데이터 저장소로 활용됩니다.

주요 기능

  • 버킷(Bucket): 파일을 저장하는 기본 단위로, 하나의 버킷 안에 수많은 파일(객체)을 저장할 수 있습니다.

  • 객체(Object): 파일 그 자체로, 메타데이터와 데이터로 이루어져 있습니다.

  • ACL(Access Control List): 각 객체와 버킷에 대해 접근 권한을 설정할 수 있는 기능입니다.

  • 버전 관리: S3는 파일의 여러 버전을 관리할 수 있습니다.

  • 라이프사이클: 파일을 자동으로 아카이브하거나 삭제할 수 있는 규칙을 설정할 수 있습니다.

2. Spring Boot와 AWS S3 연동하기

Spring Boot와 S3를 연동하기 위해서는 AWS SDK를 사용해야 합니다. Spring Boot는 다양한 AWS 서비스를 쉽게 연동할 수 있도록 라이브러리 및 설정을 지원합니다.

필수 설정 및 라이브러리 추가

implementation 'software.amazon.awssdk:s3:2.20.0'
implementation 'org.springframework.boot:spring-boot-starter-web'


AWS 자격 증명 설정

AWS 자격 증명을 설정해야 S3와 통신할 수 있습니다. 기본적으로, ~/.aws/credentials 파일에 자격 증명을 설정할 수 있습니다.

[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY

S3 클라이언트 설정
Spring Boot 애플리케이션에서 S3 클라이언트를 설정하는 방법입니다.

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class S3Config {

    @Bean
    public S3Client s3Client() {
        return S3Client.builder()
                .region(Region.AP_NORTHEAST_2) // 서울 리전
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();
    }
}


S3 파일 업로드 및 다운로드 서비스 구현

  • 파일 업로드 서비스
    S3에 파일을 업로드하는 서비스를 구현할 수 있습니다.
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

@Service
public class S3Service {

    private final S3Client s3Client;
    private final String bucketName = "your-bucket-name";

    public S3Service(S3Client s3Client) {
        this.s3Client = s3Client;
    }

    public void uploadFile(MultipartFile file) throws IOException {
        Path tempFile = Paths.get(System.getProperty("java.io.tmpdir"), file.getOriginalFilename());

        file.transferTo(tempFile.toFile());

        PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(file.getOriginalFilename())
                .build();

        s3Client.putObject(putObjectRequest, tempFile);
    }
}

+ 파일 다운로드 서비스
S3에서 파일을 다운로드하는 서비스도 쉽게 구현할 수 있습니다.

import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import software.amazon.awssdk.services.s3.S3Client;

@Service
public class S3DownloadService {

    private final S3Client s3Client;
    private final String bucketName = "your-bucket-name";

    public S3DownloadService(S3Client s3Client) {
        this.s3Client = s3Client;
    }

    public InputStream downloadFile(String fileName) {
        GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                .bucket(bucketName)
                .key(fileName)
                .build();

        return s3Client.getObject(getObjectRequest);
    }
}

컨트롤러 구현
파일을 업로드하고 다운로드할 수 있는 API를 제공합니다.

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.ResponseEntity;
import java.io.IOException;

@RestController
@RequestMapping("/s3")
public class S3Controller {

    private final S3Service s3Service;
    private final S3DownloadService s3DownloadService;

    public S3Controller(S3Service s3Service, S3DownloadService s3DownloadService) {
        this.s3Service = s3Service;
        this.s3DownloadService = s3DownloadService;
    }

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            s3Service.uploadFile(file);
            return ResponseEntity.ok("File uploaded successfully!");
        } catch (IOException e) {
            return ResponseEntity.status(500).body("File upload failed!");
        }
    }

    @GetMapping("/download/{fileName}")
    public ResponseEntity<InputStreamResource> downloadFile(@PathVariable String fileName) {
        InputStream fileStream = s3DownloadService.downloadFile(fileName);
        return ResponseEntity.ok(new InputStreamResource(fileStream));
    }
}

3. 보안 및 최적화
S3와의 연동에서 보안과 비용 최적화를 고려하는 것은 매우 중요합니다.

  • IAM 역할 및 정책: 특정 리소스에 대한 권한을 제한하는 정책을 적용해야 합니다. IAM 역할을 사용하여 S3 버킷에 대한 액세스를 최소화하는 것이 좋습니다.

  • S3 라이프사이클 정책: S3에 저장된 데이터를 비용 효율적으로 관리하기 위해, 데이터를 일정 기간 후 아카이브하거나 삭제하는 라이프사이클 정책을 설정할 수 있습니다.

  • 암호화: S3에 저장된 데이터를 암호화하는 것이 좋습니다. AWS에서 제공하는 서버 측 암호화(SSE)를 활용하면 안전하게 데이터를 보호할 수 있습니다.

  1. 마무리
    이번 글에서는 AWS S3의 기본 개념과 Spring Boot를 이용한 S3 연동 방법을 살펴보았습니다. AWS S3는 확장성과 보안성을 제공하기 때문에 다양한 애플리케이션에서 데이터 저장소로 활용할 수 있습니다. Spring Boot 애플리케이션에서 S3와 연동하면 파일 업로드 및 다운로드 기능을 쉽게 구현할 수 있으며, 비용 최적화와 보안을 고려하여 설계할 수 있습니다.
profile
꾸준히 성장하는 개발자

0개의 댓글