S3란
S3(Simple Storage Service)는 AWS가 제공하는 완전관리형 오브젝트 스토리지 서비스다. 파일을 객체(Object) 단위로 저장하고, 그 객체들을 버킷(Bucket)이라는 컨테이너에 담아 관리한다. 디스크처럼 블록 단위로 쪼개서 쓰는 EBS나 폴더 구조로 여러 서버가 공유하는 EFS와 달리 S3는 파일 하나를 통째로 키(key)라는 이름에 매핑해서 저장하는 구조다.
특징
- 확장성: 저장 용량에 사실상 제한이 없다. 몇 개의 파일이든 몇 페타바이트든 별도로 용량을 미리 할당하거나 늘릴 필요 없이 그대로 저장된다.
- 내구성: S3 Standard 기준으로 99.999999999%(11 9's)의 내구성을 설계 목표로 한다. 객체를 여러 가용 영역(AZ)에 자동으로 복제해서 저장하기 때문에, 특정 AZ 하나가 통째로 사라져도 데이터가 보존되도록 설계되어 있다.
- 가용성: 스토리지 클래스별로 다르지만 Standard 기준 99.99% 가용성을 목표로 한다. 내구성(데이터가 안 사라지는 것)과 가용성(원할 때 접근 가능한 것)은 별개의 지표라는 점이 헷갈리기 쉬운 부분이다.
- 신뢰성(일관성): 객체를 쓰면 바로 그다음 읽기 요청에서 최신 값이 보장되는 강한 읽기-후-쓰기 일관성(strong read-after-write consistency)을 제공한다. 과거에는 최종 일관성 모델이었지만 지금은 업데이트되어 이 부분을 신경 쓸 필요가 줄었다.
- 관리 기능: 버저닝(같은 키에 여러 버전 보관), 수명주기 정책(일정 기간 후 다른 스토리지 클래스로 전환하거나 삭제), 복제(다른 버킷·리전으로 자동 복사) 등을 지원한다.
서비스 기능 한눈에 보기
S3는 다음 기능들을 기본으로 제공한다.
- 스토리지 클래스: Standard(자주 접근), Standard-IA/One Zone-IA(가끔 접근), Glacier 계열(장기 보관/아카이브), Intelligent-Tiering(자동 전환) 등 접근 빈도에 따라 비용과 검색 속도가 다른 클래스를 선택할 수 있다.
- 버저닝: 같은 객체를 덮어쓰거나 삭제해도 이전 버전이 남아서 복구할 수 있다. 실수로 덮어쓴 파일을 되돌릴 때 유용하다.
- 수명주기 정책: 30일 지나면 Standard-IA로, 90일 지나면 Glacier로, 365일 지나면 삭제와 같은 규칙을 자동으로 적용한다.
- 복제(Replication): 같은 리전(SRR) 또는 다른 리전(CRR)의 버킷으로 객체를 자동 복사한다. 재해 복구나 지리적으로 가까운 곳에 데이터를 두고 싶을 때 쓴다.
- 암호화: 저장 시 암호화(SSE-S3, SSE-KMS, SSE-C)를 기본적으로 지원한다.
객체와 버킷
- 버킷(Bucket): 객체를 담는 최상위 컨테이너다. 버킷 이름은 전 세계적으로 유일해야 하고 리전을 지정해서 생성한다.
- 객체(Object): 실제 저장되는 파일 단위다. 객체는 키(파일 경로처럼 보이는 문자열), 값(실제 데이터), 메타데이터로 구성된다. S3는 폴더 구조가 실제로 존재하는 게 아니라,
images/2026/photo.jpg처럼 키 이름 자체에 /가 포함된 것뿐이고 콘솔에서 폴더처럼 보여주는 것이다.
버킷 정책 vs 사용자 정책
접근 권한을 거는 방법이 두 가지라 헷갈리기 쉽다.
- 버킷 정책(Bucket Policy): 버킷에 직접 붙이는 리소스 기반 정책이다. 이 버킷에는 어떤 계정/사용자가 접근 가능한지를 버킷 쪽에서 정의한다. JSON으로 작성하고 퍼블릭 액세스 허용처럼 버킷 전체에 적용되는 규칙을 걸 때 쓴다.
- 사용자 정책(IAM Policy): IAM 사용자나 역할에 붙이는 자격 증명 기반 정책이다. 사용자가 어떤 버킷/객체에 접근 가능한지를 사용자 쪽에서 정의한다.
둘 다 허용해야 실제로 접근이 가능하다는 점이 핵심이다. 버킷 정책이 허용해도 IAM 정책이 막고 있으면 접근이 안 되고, 반대도 마찬가지다. 저번에 IAM Role/액세스 키를 정리하면서 봤던 권한은 여러 레이어에서 동시에 평가된다는 개념이 S3에도 그대로 적용된다. 여기에 더해 버킷 단위로 퍼블릭 접근 자체를 원천 차단하는 퍼블릭 액세스 차단(Block Public Access) 설정도 있는데 이게 켜져 있으면 버킷 정책에서 퍼블릭을 허용해도 무시된다.
사용 절차
S3를 쓰는 기본 흐름은 단순하다.
버킷 생성(이름/리전 지정) → 객체 업로드 → 접근 권한 설정(버킷 정책/IAM 정책) → 애플리케이션/사용자가 접근
버킷을 만들 때 퍼블릭 액세스 차단 여부, 버저닝 사용 여부, 암호화 방식을 함께 설정하고 이후 필요에 따라 수명주기 정책이나 복제 규칙을 추가하는 식으로 운영한다.
웹사이트 호스팅
S3는 정적 웹사이트 호스팅 기능을 내장하고 있다. 버킷에서 정적 웹사이트 호스팅을 활성화하고 인덱스 문서(index.html)와 오류 문서(error.html)를 지정하면, S3가 발급하는 웹사이트 엔드포인트로 HTML/CSS/JS 같은 정적 파일을 바로 서비스할 수 있다. HTML/이미지처럼 서버 사이드 처리가 필요 없는 정적 콘텐츠에 적합하고 서버를 띄울 필요가 없어서 비용이 저렴하다.
다만 이 방식은 HTTPS를 직접 지원하지 않고 접근 속도도 버킷이 있는 리전 하나에 고정된다는 한계가 있다. 그래서 실무에서는 S3를 정적 호스팅 origin으로 두고 앞단에 CloudFront를 붙이는 구성이 일반적이다(아래에서 다시 다룸).
다양한 파일 업로드 방법
- 콘솔: AWS 웹 콘솔에서 드래그 앤 드롭으로 업로드. 소량의 파일을 수동으로 올릴 때 적합하다.
- AWS CLI:
aws s3 cp 또는 aws s3 sync 명령으로 업로드/동기화한다. 스크립트에 넣어 자동화하기 좋다.
- SDK: Python(boto3), Node.js 등 각 언어의 SDK를 통해 애플리케이션 코드 안에서 업로드한다.
- 멀티파트 업로드(Multipart Upload): 큰 파일(보통 100MB 이상 권장, 5GB 이상은 필수)을 여러 조각으로 나눠 병렬로 업로드한 뒤 합치는 방식이다. 네트워크가 끊겨도 실패한 조각만 다시 올리면 되고 전체 업로드 속도도 빨라진다.
- Presigned URL: S3 자격 증명이 없는 클라이언트(예: 사용자의 브라우저)에게 제한된 시간 동안만 유효한 업로드/다운로드 URL을 발급해주는 방식이다. 서버를 거치지 않고 클라이언트가 직접 S3에 업로드할 수 있어서 파일 업로드가 많은 웹 서비스에서 서버 부하를 줄이는 데 쓰인다.
- Transfer Acceleration: CloudFront의 엣지 로케이션을 거쳐 S3로 더 빠르게 전송하는 기능이다. 사용자와 버킷 리전이 지리적으로 먼 경우에 효과가 크다.
부정한 액세스 감지
S3에 대한 비정상적인 접근을 감지하는 방법도 여러 겹으로 구성할 수 있다.
- 서버 액세스 로깅: 버킷에 대한 모든 요청(누가, 언제, 어떤 객체에 접근했는지)을 로그 파일로 남겨 다른 버킷에 저장한다.
- CloudTrail 데이터 이벤트: 저번에 정리했던 CloudTrail을 S3의 객체 단위 작업(GetObject, PutObject 등)까지 기록하도록 설정하면 어떤 객체에 누가 접근했는지 API 호출 단위로 추적할 수 있다.
- GuardDuty S3 Protection: CloudTrail 데이터 이벤트를 분석해서 비정상적인 접근 패턴(예: 평소와 다른 위치에서의 대량 다운로드)을 탐지하고 자동으로 경고한다.
- IAM Access Analyzer: 버킷이 의도치 않게 조직 외부나 퍼블릭에 노출되어 있는지 분석해서 알려준다. 설정 실수로 버킷이 퍼블릭으로 열려 있는 경우를 사전에 잡아내는 데 유용하다.
- Macie: 버킷 안의 객체를 스캔해서 주민등록번호, 카드번호 같은 민감 정보가 포함된 파일이 있는지, 그 파일이 퍼블릭하게 노출돼 있는지를 탐지한다.
로깅(기록)과 탐지(분석/경고)가 분리되어 있다는 점이 저번에 CloudTrail/EventBridge를 정리할 때 봤던 구조와 비슷하다. 서버 액세스 로깅,CloudTrail이 기록을 남기면 GuardDuty/Access Analyzer/Macie가 그 기록을 분석해서 문제를 찾아내는 역할을 나눠 맡는다.
CloudFront와의 조합
저번에 CloudFront를 정리할 때 S3가 오리진으로 등장했는데 이 조합을 쓰는 이유를 다시 정리하면 이렇다.
사용자 ──▶ CloudFront(엣지 캐싱) ──(캐시 없을 때만)──▶ S3 버킷(오리진)
S3를 바로 공개하는 대신 CloudFront를 앞에 두면 첫째로 전 세계 엣지 로케이션에서 캐싱되어 지연 시간이 줄고 둘째로 CloudFront가 HTTPS를 지원해서 S3 정적 호스팅의 한계(HTTPS 미지원)를 보완할 수 있다. 셋째로 보안 측면에서 Origin Access Control(OAC)을 설정하면 S3 버킷 자체는 퍼블릭으로 열어두지 않고 CloudFront를 통한 요청만 허용하도록 제한할 수 있다. 즉 버킷을 완전히 비공개로 유지하면서도 CloudFront를 통해서만 콘텐츠를 서비스하는 구조가 가능해진다.
📍 참고 자료: AWS 공식 문서, 패스트캠퍼스 강의 <실전 DevOps의 모든 것>, 책 <그림으로 이해하는 AWS 구조와 기술>