ABOUT ME

통계와 개발에 대한 일기로 통개학을 운영합니다. 조그마한 도움이 되기를 바랍니다.

Today
Yesterday
Total
  • [AWS] AWS S3 생성 및 Spring 연결
    프로그램/AWS 2024. 2. 22. 21:41

     

     

    최근 진행한 프로젝트에서 AWS S3 버킷을 생성해 영상과 사진을 별도로 관리했습니다. AWS S3를 사용하는 이유로 다음과 같은 세 가지를 꼽았습니다.

     

     

    • AWS 서버를 사용하기에 업로드된 파일의 내구성(파일이 실제로 존재하는지, 99.99...99%의 내구성을 보장함)이 뛰어나다.
    • 파일을 언제든지 쓸 수 있는지의 가용성(내구성과 조금 다른 의미로 만약 파일을 당장 사용할 수 없다해도 파일이 존재한다면 내구성은 뛰어나며 가용성이 낮은 것 입니다.)이 뛰어나다.
    • 언제든지 저장 용량을 늘릴 수 있는 확장성이 뛰어나다.

     

     

    그렇다면 실제로 AWS S3 버킷을 생성하고 설정하는 과정과 Spring에 연결하는 과정을 살펴보겠습니다.

     

     

     

     


     

     

     

     

     

    | AWS S3 버킷 생성

     

     

    1. AWS S3 > 버킷 > 버킷 만들기 순서로 이동합니다.

     

     

    아래의 스크린샷에 표시된 주황색 박스 외에는 default 값으로 진행했습니다.

     

     

     

     

    모든 퍼블릭 액세스 차단을 꼭! 체크 해제 해주시기 바랍니다.

     

     

    엑세스 차단을 해제해야 이후 이미지 및 동영상 업로드시 문제없이 진행됩니다!

     

    아래와 같이 버킷 생성이 성공적으로 되었습니다. 이제 생성된 버킷에 파일을 업로드 및 호출 할 수 있도록 정책을 설정하도록 하겠습니다.

     

     

     

    2. 생성된 버킷 이름 클릭

     

     

    3. 권한 > 버킷 정책 편집 클릭

     

     

     

    4. 버킷 정책 JSON 형태로 입력 & 변경 사항 저장 클릭

     

    아래 주석에서 'sta-d' 는 저의 test 버킷 명이므로 사용자의 버킷 명으로 변경해 주셔야합니다.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Statement1",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:*",
                "Resource": "arn:aws:s3:::sta-d/*"
            }
        ]
    }

     

     

     

    이제 버킷에 대한 생성과 설정은 완료됐습니다. 아래에서는 버킷을 사용하기 위한 S3 권환을 가진 사용자 IAM을 만들어 보겠습니다.


     

     

     

     

    | 사용자 추가

     

     

     

    버킷은 생성 완료되었으며, 해당 버킷에 접근할 수 있는 권한을 부여 받을 사용자를 생성하기 위해 AWS IAM으로 이동합니다.

     

     

    1. AWS IAM > 엑세스 관리 > 사용자 > 사용자 생성 순서로 이동합니다.

     

     

    2. 사용자 이름을 입력해줍니다.

     

     

    3. 권한 설정을 아래 화면과 같이 amazonS3FullAccess로 설정해 줍니다.

     

     

    4. 검토 및 생성 페이지는 별도의 수정 없이 '사용자 생성' 버튼 클릭으로 마무리했습니다.

     

     

    여기까지 진행 하셨다면 하기와 같이 사용자가 생성된 것을 보실 수 있으며, 아직 액세스 키는 생성하지 않은 상태입니다.

     

     

     

     

     

     


     

     

     

     

     

    | 액세스 키 생성

     

     

     

    1. 사용자 이름을 클릭

     

     

     

    2. 보안 자격 증명 > 엑세스 키 만들기 클릭

     

     

     

    3. 액세스 키 모범 사례 및 대안은 보기 중 한 개를 선택해 주시면 됩니다. 기능의 차이는 없습니다.

     

     

    4. 설명 태그 설정은 선택 사항으로 저는 빈칸으로 넘어갔습니다.

     

     

     

    5. 액세스 키 검색페이지에서 나오는 엑세스 키와 비밀 엑세스 키는 깃 토근과 같이 현재 페이지를 벗어나면 다시는 확인할 수 없기에 csv 파일로 다운 받거나 어딘가에 꼭 백업을 해두어야 합니다! 만약 키 백업을 못하신 경우 새로운 액세스 키를 생성해 사용하셔야 합니다.

     

     

     

     

     

     

    | Spring 연결 with gradle, yml

     

     

    1. gradle에 dependency 추가

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

     

     

    2. yml 생성

    cloud.aws.credentials.access-key: 사용자 access key

    cloud.aws.credentials.secret-key: 사용자 secret key

    설정도 들어가야하며 저는 별도의 secret 관련 yml을 만들어 사용해 해당 파일에는 없습니다.

     

    추가로 file size를 300mb로 설정해주었습니다. default는 20mb이었던 것으로 기억합니다.

    cloud:
      aws:
        s3:
          bucket: sta-d
        stack.auto: false
        region.static: ap-northeast-2
    spring:
      servlet:
        multipart:
          max-file-size: 300MB
          max-request-size: 300MB

     

     

    3. config 생성

    import com.amazonaws.auth.AWSStaticCredentialsProvider;
    import com.amazonaws.auth.BasicAWSCredentials;
    import com.amazonaws.services.s3.AmazonS3Client;
    import com.amazonaws.services.s3.AmazonS3ClientBuilder;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @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;
    
        /**
         * @AmazonS3Client : AWS S3를 연결하기 위한 객체
         * @BasicAWSCredentials : 사용자에 대한 액세스 키, 비밀번호 키
         */
        @Bean
        public AmazonS3Client amazonS3Client() {
            BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
            return (AmazonS3Client) AmazonS3ClientBuilder.standard()
                    .withRegion(region)
                    .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                    .build();
        }
    }

     

     

    4. service 작성

    service에서 동영상 업로드 관련 부분만 기재해 드렸습니다. UUID로 파일명이 겹치지 않게 설정하였으며(겹치는 경우 파일을 덮어버립니다), S3에는 ObjectMetadata라는 별도의 파일로 업로드가 가능해 MultiparFile의 자료를 ObjectMetadata로 변환해 업로드 후 해당 video의 url을 추출하는 과정입니다.

    @Value("${cloud.aws.s3.bucket}")
    private String bucket;
    
    @Transactional(readOnly = false)
    public String uploadJustVideoS3(MultipartFile justVideo) {
        try {
            String justVideoName = UUID.randomUUID().toString().replace("-", "") + StringUtils.cleanPath(justVideo.getOriginalFilename());
            
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(justVideo.getContentType());
            metadata.setContentLength(justVideo.getSize());
            amazonS3Client.putObject(bucket, "video/" + justVideoName, justVideo.getInputStream(), metadata);
    
            String justVideoUrl = amazonS3Client.getUrl(bucket, "video/" + justVideoName).toString();
            return justVideoUrl;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

     

     

    5. controller 작성

    controller에서 동영상 업로드 관련 부분만 기재해 드렸으며, Spring을 사용해 MultipartFile 타입으로 동영상을 받았습니다.

    @PostMapping("/upload/video")
    public ResponseEntity<ApiResponse<String>> uploadJustVideo(@RequestParam("file") MultipartFile justVideo) {
        String videoUrlPath = videoPostService.uploadJustVideoS3(justVideo);
        if (videoUrlPath == null)
            return new ResponseEntity<>(ApiResponse.createError("video error"), HttpStatus.BAD_REQUEST);
        return new ResponseEntity<>(ApiResponse.createSuccess(videoUrlPath), HttpStatus.OK);
    }

     

     

     

     

     

    요번 포스터에서는 간단하게 AWS S3의 기본적인 설정을 알아보았습니다. 이 외에도 파일 자동삭제 기간 등 설정해 주어야 하는 부분이 많아 기회가 된다면 추후 포스팅 하도록 하겠습니다. 추가적으로 포스트맨으로 test 하실 경우 form-data로 자료를 전송해 test하시기 바랍니다.

Designed by Tistory.