Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

56장. S3 — 객체 스토리지의 기본

이 장에서 말하고자 하는 것

앞 장에서 객체 스토리지의 개념을 봤다.

이제 그 대표 주자

Amazon S3 (Simple Storage Service)

를 본다.

S3는 AWS에서 가장 오래된 서비스이자 가장 많이 쓰이는 서비스다.


1. 기본 단위 — 버킷과 객체

버킷 "msa-uploads"
 ├─ users/123/profile.png
 ├─ orders/2025/01/15/order-123.json
 └─ static/app.a3f2c.js
  • 버킷(Bucket) : 글로벌 고유한 이름의 컨테이너
  • 객체(Object) : 키(경로) + 값(데이터) + 메타데이터

폴더는 사실 가짜다 — users/123/profile.png 는 한 객체의 키 문자열.


2. 버킷 이름은 글로벌

S3 버킷 이름은 전 세계에서 유일 해야 한다.

이미 누가 쓰는 이름 → 만들 수 없다

운영에서는 회사/조직 식별자 + 환경 + 용도 패턴을 쓴다.

acme-prod-uploads
acme-prod-logs
acme-dev-static

3. S3는 사실상 무제한

  • 객체 크기 최대 5TB
  • 버킷당 객체 수 제한 없음
  • 처리량 자동 확장

용량 걱정 없이 쓴다는 게 S3의 첫 번째 장점


4. 강한 일관성

2020년부터 S3는 read-after-write consistency 가 기본이다.

PUT 직후 GET → 방금 쓴 내용을 반드시 받는다

옛날에는 결국 일관성(eventual)이었지만 지금은 아니다.


5. 권한 — Public이 아니다, 항상

S3 버킷은 기본적으로 비공개다.

Public Access Block ON  ← 항상 켠다

권한은 두 방식으로 준다.

  • IAM 정책 — 누가(주체) 무엇을 할 수 있는가
  • 버킷 정책 — 이 버킷에 누가 접근할 수 있는가

6. 사전 서명 URL — 임시 권한

직접 노출하지 않고 객체에 일시 접근을 주는 방식이다.

서버 → 사용자에게 "5분 동안 유효한 URL" 전달
사용자 → 그 URL로 직접 S3 GET/PUT

다음 58장에서 자세히 본다.


7. CloudFront와 함께 — 정적 호스팅 표준

S3 (비공개, OAC)
  ↑
CloudFront (HTTPS, 캐시)
  ↑
사용자

이게 정적 자원의 표준 모양이다 (39장).


8. 우리 서비스에서

[S3 버킷들]
 ├─ static          → SPA 빌드 결과 (CloudFront 노출)
 ├─ uploads         → 사용자 업로드 (사전 서명 URL)
 ├─ ecs-logs        → ECS 로그 백업
 └─ data-archive    → 분석용 백업

용도별로 버킷을 분리한다.

  • 권한이 다르다
  • 수명 주기가 다르다
  • 비용 분석이 쉬워진다

9. 직접 확인해보기 — CLI

aws s3 mb s3://msa-uploads

aws s3 cp ./profile.png s3://msa-uploads/users/123/profile.png

aws s3 cp s3://msa-uploads/users/123/profile.png ./

aws s3 ls s3://msa-uploads/users/123/

aws s3 sync ./build s3://msa-static/

s3 sync 는 정적 배포에 가장 자주 쓴다.


10. 코드로는 이렇게 생겼다 — Terraform

resource "aws_s3_bucket" "uploads" {
  bucket = "msa-prod-uploads"
}

resource "aws_s3_bucket_public_access_block" "uploads" {
  bucket = aws_s3_bucket.uploads.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_versioning" "uploads" {
  bucket = aws_s3_bucket.uploads.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "uploads" {
  bucket = aws_s3_bucket.uploads.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

네 가지 (생성 + Public 차단 + 버전 + 암호화) 가 운영 출발선이다.


11. 이렇게 쓰면 망한다 — 안티패턴

안티패턴 1. Public Access Block을 끈다

대부분의 S3 노출 사고가 여기서 시작된다.

항상 켠다. 공개가 필요하면 CloudFront + OAC로

안티패턴 2. 같은 버킷에 모든 걸 섞는다

권한 · 수명 · 비용이 다 섞인다.

용도별 버킷 분리

안티패턴 3. versioning을 안 켠다

실수로 덮어쓰면 복구가 안 된다.

안티패턴 4. 사용자 업로드에 원본 파일명을 그대로 쓴다

충돌 · 인젝션 위험.

UUID / hash 로 키를 생성한다


12. 한 줄로 정리

S3는 글로벌 단위의 버킷 안에 객체를 HTTP API로 다루는 무제한 저장소다


13. 이 장의 핵심 정리

  1. S3의 단위는 버킷(글로벌 고유) + 객체(키 + 값) 다.
  2. 폴더는 가짜다. 키 문자열일 뿐.
  3. 2020년 이후 강한 일관성을 보장한다.
  4. Public Access Block은 항상 켜고, 공개는 CloudFront + OAC로.
  5. 운영 출발선: 버킷 + Public 차단 + 버전 + 암호화.
  6. 용도별 버킷을 분리한다.