AWS S3 Bucket을 이용한 이미지 업로드 + CloudFront설정
안녕하세요! 오늘은 Interior 프로젝트를 진행하면서 웹 서비스에서 이미지를 효과적으로 보여주기 위해 AWS
의 S3 버킷
과 CloudFront
를 활용하는 방법에 대해 자세히 알아보도록 하겠습니다.
S3의 여러 가지 장점이있는데요 ❗ ❗
- 💡 내구성과 안정성: AWS의 S3는 데이터의 내구성과 안정성을 보장합니다. 데이터가 여러 복제본에 걸쳐 저장되므로 데이터 손실 우려가 줄어듭니다.
- 💡 확장성: S3는 거의 무한한 확장성을 제공하므로 대용량 데이터를 저장하고 처리할 수 있습니다.
- 💡 다양한 데이터 관리 기능: 버전 관리, 암호화, 액세스 제어 등 다양한 데이터 관리 기능을 제공하여 데이터를 보다 효율적으로 관리할 수 있습니다.
- 💡 저렴한 비용: S3는 사용한 만큼만 비용을 지불하므로 비용을 절감할 수 있습니다. S3 프리 티어 : 표준 스토리지 5GB, GET 요청 20,000 건 , PUT 요청 2,000 건이 포함됩니다.
그러나 S3를 직접 사용할 때 발생할 수 있는 요금 부담을 고려하여 클라이언트에게 빠르고 안정적인 서비스를 제공하기 위해 CloudFront를 사용할 수 있습니다. CloudFront
는 전 세계에 분산된 에지 로케이션을 통해 콘텐츠를 배포하므로 사용자가 데이터에 더 빠르게 액세스 할 수 있습니다. 또한 데이터를 캐싱하여 웹 서비스의 성능을 향상하고 전송 비용을 절감할 수 있습니다.
이제 S3 버킷을 설정하여 웹 서비스에 이미지를 저장하고 CloudFront를 통해 이 이미지를 최적화된 방식으로 띄워 보겠습니다~
Bucket 생성 및 설정하기
✅ 버킷을 만들어 줍니다.
✅ 여기서 버킷이름은 고유한 이름이기 때문에 어떠한 다른 버킷과도 이름이 중복되어서는 안 됩니다
❗ ❗
그리고 바로 버킷 정책
도 설정해 줍니다.
✅버킷 ARN
부분에 있는 것을 복사해서 아래 Resource
로 복사 붙여 넣기 하면 됩니다
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "{위의 ARN}/*"
}
]
}
사용자 생성하기
자, 다음 단계는 S3에 접근할 사용자를 생성하는 것입니다.🙂
AWS에서는 사용자를 통해 서비스에 대한 액세스 권한을 관리합니다. 사용자를 생성함으로써 개별적으로 액세스 권한을 부여하고 관리할 수 있습니다. 특히 S3와 같은 스토리지 서비스를 사용할 때는 데이터의 무단 액세스를 방지하기 위해 사용자를 생성하여 적절한 권한을 할당하는 것이 필요합니다.
✅ 우리는 AmazonS3FullAccess로 권한을 설정하여 만들겠습니다.
✅ 이제 이 액세스 키와 비밀 액세스키를 저장하여 나중에 SpringBoot application.yml파일에 설정해 주겠습니다~
SpringBoot 코드
build.gradle
dependencies에 라이브러리를 먼저 추가해 줍니다.
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
아래의 코드는 민감한 정보이니 application-secret.yml
파일에 설정합니다. 설정방법을 모르시겠다면 아래의 포스팅을 참고해 주세요!
❗
Gitignore
설정 방법 >> https://developing-mango.tistory.com/32
❗
GitHub Actions
(배포시) 시크릿 설정하는 방법 >> https://developing-mango.tistory.com/65
cloud:
aws:
s3:
bucket: <S3 bucket 이름>
credentials:
access-key: <AWS 사용자 액세스 키>
secret-key: <AWS 사용자 비밀 액세스 키>
region:
static: ap-northeast-2
auto: false
stack:
auto: false
S3Config
는 Spring 프레임워크에서 AWS S3에 접근하기 위한 설정을 담당합니다. S3Config 통해 우리는 Spring 애플리케이션에서 AWS S3를 사용하기 위한 클라이언트를 설정하고, 필요한 인증 정보와 리전 정보를 외부에서 주입받을 수 있습니다.
@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 credentials = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client) AmazonS3ClientBuilder
.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
}
}
자 다음은 기초적인 파일 업로드
구현 방법입니다.
자세한 파일 업로드 구현 방법을 알고싶으시다면 아래 포스팅을 참고해주세요
❗ 파일업로드 프론트 > https://developing-mango.tistory.com/60
❗ 파일업로드 백엔드 > https://developing-mango.tistory.com/59
@Service
@RequiredArgsConstructor
public class S3UploadService {
private final AmazonS3 amazonS3;
@Value("${cloud.aws.s3.bucket}")
private String bucket;
public String saveFile(MultipartFile multipartFile) throws IOException {
String originalFilename = multipartFile.getOriginalFilename();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(multipartFile.getSize());
metadata.setContentType(multipartFile.getContentType());
amazonS3.putObject(bucket, originalFilename, multipartFile.getInputStream(), metadata);
return amazonS3.getUrl(bucket, originalFilename).toString();
}
}
saveFile 메서드는 MultipartFile을 입력으로 받아서 S3에 파일을 업로드하고 해당 파일의 URL을 반환합니다. 업로드된 파일은 원본 파일의 이름을 그대로 사용하여 저장됩니다. 먼저, multipartFile에서 원본 파일의 이름을 가져옵니다. 그런 다음, 파일의 메타데이터를 생성하고 설정합니다. 메타데이터에는 파일의 크기와 콘텐츠 유형이 포함됩니다.
AmazonS3 객체의 putObject
메서드를 사용하여 S3 버킷에 파일을 업로드
합니다. 이때 버킷 이름과 업로드할 파일의 이름, 파일의 입력 스트림 및 메타데이터가 전달됩니다.
마지막으로, AmazonS3 객체의 getUrl 메서드를 사용하여 업로드된 파일의 URL을 생성하고 반환합니다. 나중에 이 URL을 갖고 CloudFront의 DNS와 결합하여 RDS에 저장하여 관리하면 됩니다.
한번 업로드해봅시다!
@PostMapping("/")
public String coverImageUpload(CoverUploadDto coverUploadDto) throws IOException {
String amazonBucket = imageService.커버사진업로드(coverUploadDto);
System.out.println("-------------------------------------------");
System.out.println(amazonBucket);
return "redirect:/";
}
✅ 아래는 결과물입니다. 업로드에 성공했네요!
✅ 버킷에도 업로드가 잘 된것으로 확인됩니다.
감사합니다!!!!😊
CloudFront로 Bucket에 저장된 이미지 불러오기
✅ 이후에 나온 배포 도메인이름을 복사해서 Spring 코드에 아래와 같이 적용하시고 DB에 저장하시면 쉽게 이미지를 불러오실 수 있습니다. 😁
https://{CloudFront 도메인 이름}/{아마존 버킷에 저장된 image url}
✅ 아래 코드 처럼 적용 시켜 줍니다.
@PostMapping("/")
public String coverImageUpload(CoverUploadDto coverUploadDto) throws IOException {
String amazonBucket = imageService.커버사진업로드(coverUploadDto);
System.out.println("----------------S3 저장 링크---------------------------");
System.out.println(amazonBucket);
String ads = "https://{CloudFront 배포도메인이름}/"+amazonBucket.split("/")[amazonBucket.split("/").length-1];
System.out.println("--------------------Cloud Front 링크-----------------------");
System.out.println(ads);
return "redirect:/";
}
✅ 아래는 sout을 통해 링크가 잘 생성되는지 테스트해봤습니다! 🤗
긴 글 읽어주셔서 감사합니다~
'Backend > 🌿Spring' 카테고리의 다른 글
[SpringBoot] 좋아요 기능 구현 및 생각 (0) | 2024.03.27 |
---|---|
[SpringBoot] 협업을 위한 Swagger 사용법 (0) | 2024.03.11 |
[Spring Boot] @Value 어노테이션을 활용한 설정 값 관리 (0) | 2024.02.14 |
[Spring Boot] 사진 업로드 기능 구현하기 Back-end , 1편 (1) | 2024.01.23 |
[JPA/Error] 무한 참조 문제 해결하기 @JsonIgnoreProperties 활용 (0) | 2024.01.21 |