S3(Simple Storage Service)

- AWS에서 제공하는 파일 서버로써, 트래픽 증가로 인한 장비 증설 작업 기능을 대행한다.
- 또한, 파일에 대한 접근 권한을 지정 할 수 있어서 서비스를 호스팅 용도로 사용하는 것을 방지 할 수 있다.
- 사용 이유?
- 확장성 - 거의 무제한의 데이터 저장 공간을 제공한다
- 내구성 - 99.999999%의 내구성을 가진다
- 가용성 - 서버에 잠시 장애가 생겨도, s3의 데이터에 대한 접근이 가능하다.
⇒ 실 프로덕션 환경에서는 s3을 이용해 자료를 관리한다.
- 주요 용어
- 객체(Objects) - AWS S3에 저장된 데이터
- 버킷(Buckets) - 객체가 파일이면, 버킷은 객체들을 그룹핑한 최상위 디렉토리이다. 버킷 단위로 지역을 정할 수 있고, 일괄적인 접속 및 접근 제한 정책을 적용 할 수 있다.
- 키(Keys) - 버킷 내 객체 고유 식별자를 뜻하며, 보통 “디렉토리 + 파일명"로 명명됨
S3 구축하기
1. S3 버킷 생성
Create Bucket
버튼을 클릭하여 새로운 S3 버킷을 생성한다. 버킷 이름과 리전을 설정하고, 필요한 경우 버킷 설정을 커스터마이징한다.- 버킷 이름: 전 세계적으로 고유해야 한다.
- 리전: 웹 서버와 가까운 리전을 선택하여 지연 시간을 최소화한다.
- 객체 소유권: 다른 AWS 계정에서의 접근을 허락할지에 대한 선택

- 이 버킷의 퍼블릭 액세스 차단 설정
- 활성화 시
- 이 설정을 활성화하면 버킷과 그 안의 모든 객체에 대한 퍼블릭 액세스가 완전히 차단된다(해당 버킷과 객체들이 인터넷을 통해 공용으로 접근할 수 없음을 의미)
- 주로 외부에서 접근할 필요가 없는 중요한 데이터나 내부용 파일을 저장하는 버킷에 사용
- 비활성화 시
- 버킷과 객체에 대해 퍼블릭 액세스를 허용할 수 있는 설정을 개별적으로 조정할 수 있다
- 정적 콘텐츠를 호스팅하기 위해 퍼블릭 액세스를 허용해야 하는 경우(외부 고객이나 파트너에게 데이터를 공개적으로 제공해야 하는 경우) 사용
- 비활성화를 해 준다고 해서, 누구나 s3의 데이터를 조회할 수 있는것은 아니다. 명시적으로 그 객체나 버킷에 대해 퍼블릭 액세스를 허용하는 설정(정책 설정, ACL 허용 등)이 필요하다.
- 버킷 버전 관리
- 기본 암호화

- S3 버킷 정책 예시
- 버캣 정책 예제, 정책 생성기를 사용해 버킷의 정책을 설정할 수 있다.
YOUR_BUCOKET_NAME
안의 데이터를 모든 사용자(/*
) 가 GET, PUT, DELETE 할 수 있는 예제
{
"Version": "2012-10-17",
"Id": "Policy1723306467760",
"Statement": [
{
"Sid": "{{ID}}",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::{{YOUR_BUCOKET_NAME}}/*"
}
]
}
2. IAM으로 S3 엑세스 관리

- S3을 사용하기 위해선 IAM을 사용한 key 발급이 필요하다.
- 사용자 그룹 & 사용자를 만들고, AmazonS3FullAccess 정책을 추가해준다.

- S3 접근을 위핸 Access Key 발급을 해준다.
- IAM → 사용자 → 액세스 키 만들기
- 사용 사례는 AWS 외부에서 실행되는 애플리케이션를 선택한 후 키를 발급하자.
- 키 발급 후, Access Key와 Secret Key는 반드시 저장해준다.
3. 스프링에서 S3 사용하기
- build.gradle에 추가
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
- S3Config
@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 awsCred = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client)AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCred))
.build();
}
}
- S3에 데이터 올리기, 받아오기
public class ImageService {
private final AmazonS3Client amazonS3Client;
@Value("${cloud.aws.bucket}")
private String bucket;
@Transactional
public String saveFile(MultipartFile file) throws IOException {
String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
metadata.setContentType(file.getContentType());
amazonS3Client.putObject(bucket, fileName, file.getInputStream(), metadata);
return amazonS3Client.getUrl(bucket, fileName).toString();
}
@Transactional
public File loadFile(String fileName) {
File file = new File(fileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(amazonS3Client.getObject(bucket, fileName).getObjectContent().readAllBytes());
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
}
Share article