# [AWS] S3(Simple Storage Service)์„œ๋ฒ„์™€ Spring Boot ์—ฐ๋™
Study Repository

[AWS] S3(Simple Storage Service)์„œ๋ฒ„์™€ Spring Boot ์—ฐ๋™

by rlaehddnd0422

์ง„ํ–‰์ค‘์ด๋˜ ํ”„๋กœ์ ํŠธ์— ํŒŒ์ผ ์—…๋กœ๋“œ ๊ธฐ๋Šฅ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ex) ๊ฒŒ์‹œ๊ธ€์„ ์—…๋กœ๋“œ ํ•  ๋•Œ ์ด๋ฏธ์ง€๋„ ํ•จ๊ป˜ ์—…๋กœ๋“œ, ํšŒ์›์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๋ฅผ ๋“ฑ๋ก

ํŒŒ์ผ ์—…๋กœ๋“œ์˜ ๊ฒฝ์šฐ, EC2 ์„œ๋ฒ„๊ฐ€ ์•„๋‹Œ ๋กœ์ปฌ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด yml์— ์ œ ๊ฐœ์ธ PC์— ์ €์žฅํ•˜๋„๋ก ์„ค์ •ํ•ด์ฃผ์—ˆ๋Š”๋ฐ, ๋ฐฐํฌ๋ฅผ ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜๋ฉด์„œ ํŒŒ์ผ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ S3 ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

upload:
  post:
    image:
      location: /Users/kdo6301/Desktop/sharing_platform_server/post/
  member:
    image:
      location: /Users/kdo6301/Desktop/sharing_platform_server/member/

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Spring Boot์—์„œ AWS S3 ์„œ๋ฒ„๋ฅผ ์ด์šฉํ•˜์—ฌ ํŒŒ์ผ ๊ด€๋ฆฌ๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


1. S3 (Simple Storage Service) ๋ž€?

  • AWS์—์„œ ์ง€์›ํ•˜๋Š” ํŒŒ์ผ ๊ด€๋ฆฌ ์Šคํ† ๋ฆฌ์ง€ ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.
  • ํ™•์žฅ์„ฑ๊ณผ ๋‚ด๊ตฌ์„ฑ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  • ๊ฐ€์ž…์ผ ๊ธฐ์ค€ 12๊ฐœ์›”๊ฐ„ ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. ์‚ฌ์ „ ์ค€๋น„

  • S3 ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” AWS์—์„œ ๋ฒ„ํ‚ท๊ณผ IAM์„ ๋จผ์ € ์ƒ์„ฑํ•ด์ฃผ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฒ„ํ‚ท : ๋‹ค์ˆ˜์˜ ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ ( ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํŒŒ์ผ ์‹œ์Šคํ…œ์ด๋ผ๊ณ  ๋ณด๋ฉด ๋จ )
  • IAM : S3์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉ์ž ์ •๋ณด

์‚ฌ์šฉ์ž(IAM) ์ƒ์„ฑ

1. AWS ๊ฒ€์ƒ‰์ฐฝ์— iam ์„ ๊ฒ€์ƒ‰ํ•œ ํ›„ ์ฃผ์š” ๊ธฐ๋Šฅ - ์‚ฌ์šฉ์ž ํด๋ฆญ

2. ์›ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„ ์ง€์ • - ๋‹ค์Œ 

3. ์•„๋ž˜์™€ ๊ฐ™์ด ๊ถŒํ•œ ์„ค์ • - ๋‹ค์Œ

4. ๊ฒ€ํ†  ๋ฐ ์ƒ์„ฑ - ์‚ฌ์šฉ์ž ์ƒ์„ฑ

5. ์•ก์„ธ์Šค ํ‚ค ์„ค์ • - ์‚ฌ์šฉ์ž ์ด๋ฆ„ ํด๋ฆญ 

6. ์š”์•ฝ - ์•ก์„ธ์Šค ํ‚ค ๋งŒ๋“ค๊ธฐ

7. ์•ก์„ธ์Šค ํ‚ค ์‚ฌ์šฉ ์‚ฌ๋ก€ ์„ ํƒ - ์•„๋ฌด๊ฑฐ๋‚˜ ์„ ํƒ ํ•ด๋„ ok

8. ์›ํ•˜๋Š” ํƒœ๊ทธ ์ž‘์„ฑ ( ์„ ํƒ ) ํ›„ - ์•ก์„ธ์Šค ํ‚ค ๋งŒ๋“ค๊ธฐ

 

9. csv ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ( ์ด ํŒŒ์ผ์—๋Š” ๊ณต๊ฐœํ‚ค์ธ Access Key์™€ , ๋น„๋ฐ€ํ‚ค์ธ Secret Key ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒŒ์ผ ๊ด€๋ฆฌ์— ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค )

 

์ด์ œ S3์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ IAM์— ๋Œ€ํ•œ ์„ค์ •์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„ํ‚ท์„ ์ƒ์„ฑํ•ด๋ด…์‹œ๋‹ค.

๋ฒ„ํ‚ท ์ƒ์„ฑ

1. ๊ฒ€์ƒ‰์ฐฝ์— s3 ๊ฒ€์ƒ‰

2. ๋ฒ„ํ‚ท ๋งŒ๋“ค๊ธฐ ํด๋ฆญ

3. ์ผ๋ฐ˜ ๊ตฌ์„ฑ - ๋ฒ„ํ‚ท ์ด๋ฆ„ ์ง€์ •

4. Public Access ์ฐจ๋‹จ ํ•ด์ œ ๋ฐ ๋ฒ„ํ‚ท ๋งŒ๋“ค๊ธฐ ํด๋ฆญ

 

ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜๋‚˜์˜ ๋ฒ„ํ‚ท์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์‚ฌ์ „ ์ค€๋น„๊ฐ€ ๋ชจ๋‘ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ด์ œ Spring boot์— ์ด ๋ฒ„ํ‚ท๊ณผ ์—ฐ๋™ํ•ด๋ด…์‹œ๋‹ค.


3. Spring Boot์™€ ์—ฐ๋™

1. build.gradle์— ์˜์กด๊ด€๊ณ„ ์ถ”๊ฐ€

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

 

2.  IAM ์ƒ์„ฑ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ csv ํŒŒ์ผ์˜ ๊ณต๊ฐœํ‚ค์™€ ๋น„๋ฐ€ํ‚ค, ๊ทธ๋ฆฌ๊ณ  ๋ฒ„ํ‚ท์„ ์ƒ์„ฑํ•  ๋•Œ ์ง€์ •ํ•œ ๋ฒ„ํ‚ท ์ด๋ฆ„์„ yml์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.

  • ์ด ๋•Œ AccessKey์™€ SecretKey ์ •๋ณด๋Š” github์— ์˜ฌ๋ผ๊ฐ€๊ฒŒ ๋˜๋ฉด ํ•ดํ‚น์œผ๋กœ ์ธํ•œ ๊ณผ๊ธˆ ์œ„ํ—˜์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ yml ํŒŒ์ผ์„ gitignore๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฐ˜๋“œ์‹œ github์— ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋„๋ก ํ•ฉ์‹œ๋‹ค.
  • cloud.aws.region.static: ap-northease2  : ์ง€์—ญ ํ•œ๊ตญ ๊ณ ์ •

3) ์Šคํ”„๋ง ์„ค์ • ์ถ”๊ฐ€

@Configuration
public class S3Config {

    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;
    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;
    @Value("${cloud.aws.region.static}")
    private String region;

    @Bean
    public AmazonS3Client amazonS3Client() {
        BasicAWSCredentials awsCredentials   = new BasicAWSCredentials(accessKey, secretKey);
        return (AmazonS3Client) AmazonS3ClientBuilder.standard()
                .withRegion(region)
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .build();
    }
}

4. ๋กœ์ปฌ ์ €์žฅ โžก๏ธ S3 ์„œ๋ฒ„์˜ ๋ฒ„ํ‚ท์— ์ €์žฅํ•˜๋„๋ก  Refactoring

PostFileService

@Service
@RequiredArgsConstructor
public class PostFileService {

    @Value("${cloud.aws.s3.bucket}")
    private String BUCKET;
    private final AmazonS3Client amazonS3Client;


    public void upload(MultipartFile file, String filename) {
        try {
            ObjectMetadata metadata= new ObjectMetadata();
            metadata.setContentType(file.getContentType());
            metadata.setContentLength(file.getSize());
            amazonS3Client.putObject(BUCKET + "/post", filename, file.getInputStream(), metadata);
        } catch(IOException e) {
            throw new FileUploadFailureException();
        }
    }

    public void delete(String fileName){
        DeleteObjectRequest request = new DeleteObjectRequest(BUCKET + "/post", fileName);
        amazonS3Client.deleteObject(request);
    }
}
  • ๊ธฐ์กด์—๋Š” upload()๋ฉ”์†Œ๋“œ์—์„œ try/catch๋ฌธ์œผ๋กœ ๋กœ์ปฌ์—์„œ ํ•„๋“œ์— ์ง€์ •ํ•œ ์œ„์น˜์— ์ ‘๊ทผํ•˜์—ฌ ํŒŒ์ผ์„ ์ €์žฅํ•˜๊ณ , ๋งŒ์•ฝ IOException์œผ๋กœ ํŒŒ์ผ์—…๋กœ๋“œ์— ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ Customํ•œ extended RuntimeException์ธ FileUploadException์„ ๋˜์ง€๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ์กด์—๋Š” delete() ๋ฉ”์†Œ๋“œ๋„ ํ•„๋“œ์— ์ง€์ •ํ•œ ์œ„์น˜์— ์ ‘๊ทผํ•˜์—ฌ ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • S3 ์Šคํ† ๋ฆฌ์ง€ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•œ ์ดํ›„ ๋ถ€ํ„ฐ๋Š” ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์ด yml์— ์ง€์ •ํ•ด์ค€ BUCKET์˜ ํด๋”์— ์ ‘๊ทผํ•˜์—ฌ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๊ณ , ์ง€์šธ ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค.

5. Postman Test

์—…๋กœ๋“œ ํ…Œ์ŠคํŠธ

1) ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ฑ ์š”์ฒญ with ํŒŒ์ผ 

  • ์ด ๋•Œ ๋ณ„๋„๋กœ ์ƒ์„ฑํ•ด๋‘” Post Image ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํŒŒ์ผ์˜ originName๊ณผ uniqueName์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. (for ์‚ฌ์šฉ์ž๊ฐ€ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , ์‚ญ์ œํ•  ๋•Œ S3์— ์ €์žฅ๋œ ํŒŒ์ผ์ด ๋ฌด์—‡์ธ์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด์„œ)

2) ๋ฒ„ํ‚ท์— ํŒŒ์ผ์ด ์ž˜ ์ €์žฅ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ํ…Œ์ŠคํŠธ - ์ด๋ฏธ์ง€ ํŒŒ์ผ ์‚ญ์ œ 

1) ์ˆ˜์ • ์š”์ฒญ

 

2) ๋ฒ„ํ‚ท์—์„œ ์‚ญ์ œ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

  • ์ฐธ๊ณ ๋กœ ์ด๋ฏธ์ง€ ์‚ญ์ œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • API์—์„œ Post Image๋ฅผ ์œ„ํ•œ ๋ณ„๋„์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ์š”์ฒญ API์˜ ํผ๋ฐ์ดํ„ฐ์— deleteImageNames๋กœ ์ž‘์„ฑํ•œ originName๊ณผ ์ผ์น˜ํ•˜๋Š” ํŒŒ์ผ์˜ uniqueName์„ S3์„œ๋ฒ„์—์„œ ์‚ญ์ œํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค)

 

<์ฐธ๊ณ  ์ž๋ฃŒ>

 

[Spring boot] AWS S3 ๋ฅผ ์ด์šฉํ•œ ํŒŒ์ผ ์—…๋กœ๋“œ

๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉฐ ์ด๋ฏธ์ง€ ์„œ๋ฒ„๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด AWS S3 ๋ฒ„ํ‚ท์„ ๋งŒ๋“ค๊ณ  Spring ์„ ์—ฐ๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•ด๋ณด์•˜๋‹ค. [1] AWS S3 ๊ฐœ์š” AWS S3 ๋ž€? S3๋Š” Simple Storage Service ์˜ ์•ฝ์ž๋กœ ์ฃผ๋กœ ํŒŒ์ผ ์„œ๋ฒ„๋กœ ์‚ฌ์šฉ

gaeggu.tistory.com

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ