들어가며
버전 관리는 켜두면 좋은 기능이다. 실수로 덮어써도, 지워도 되돌릴 수 있다. 그래서 처음에는 전 버킷에 일괄 적용하는 쪽으로 생각했다.
그런데 버킷마다 쌓이는 방식이 달랐다. 매번 새 파일명으로 쌓이는 버킷이 있고, 같은 이름을 계속 덮어쓰는 버킷이 있다. 전자는 켜도 이전 버전이 거의 안 생기고, 후자는 켜는 순간부터 저장량이 두 배로 늘어날 수 있다. 같은 설정인데 결과가 반대다. 그래서 일괄 적용 대신 판단 기준부터 만들었다.
버전 관리란
S3 버킷 버전 관리를 활성화하면, 같은 키(파일명)로 업로드하거나 삭제할 때 이전 버전이 보존된다.
| 동작 | 버전 관리 OFF | 버전 관리 ON |
|---|---|---|
| 파일 덮어쓰기 | 원본 영구 소실 | 이전 버전 보존, 복구 가능 |
| 파일 삭제 | 영구 삭제 | 삭제 마커만 추가, 실제 데이터 보존 |
| 랜섬웨어 공격 | 복구 불가 | 이전 버전으로 롤백 가능 |
이전 버전이 생기는 조건
이전 버전은 "같은 파일명으로 다시 업로드하거나 삭제할 때"만 생긴다. S3에는 파일 내용 일부를 수정하는 개념이 없고, 항상 객체 전체를 새로 올리는 구조이기 때문이다.
| 동작 | 이전 버전 생김 | 설명 |
|---|---|---|
| 같은 파일명으로 다시 업로드 | 생김 | 기존 파일이 이전 버전으로 보존 |
| 파일 삭제 | 생김 | 삭제 마커 추가, 원본은 이전 버전으로 보존 |
| 새 파일명으로 업로드 | 안 생김 | 새 객체라서 이전 버전 없음 |
| 파일 읽기/다운로드 | 안 생김 | 변경이 아님 |
즉 EDI 허브처럼 매번 다른 파일명으로 쌓이는 구조면 이전 버전이 거의 안 생긴다. 같은 파일명을 반복해서 덮어쓰는 경우(프론트엔드 빌드 배포 등)에만 쌓인다.

같은 기능을 켜도 한쪽은 저장량이 그대로고, 다른 쪽은 날마다 늘어난다. 버전 관리의 비용은 기능이 아니라 사용 패턴이 결정한다.
기존 시스템 영향
버전 관리를 켜도 기존 동작에는 영향이 없다.
- 파일 읽기와 쓰기: 동일하게 동작 (버전을 지정하지 않으면 항상 최신 버전 반환)
- CloudFront 연동: 영향 없음
- Presigned URL: 동일하게 동작
- SDK와 CLI: 변경 없음
유일한 변화는 덮어쓰기와 삭제 시 이전 버전이 남아 스토리지 사용량이 늘어날 수 있다는 점이다.
삭제했는데 용량이 줄지 않는다
버전 관리를 켠 뒤 가장 헷갈리는 지점이다. 파일을 지웠는데 버킷 크기가 그대로다.
[버전 관리 OFF]
delete → 객체 사라짐, 용량 감소
[버전 관리 ON]
delete → 삭제 마커가 최신 버전으로 추가됨
원본은 이전 버전으로 그대로 남아 있음
목록에서는 안 보이고, 용량은 그대로
콘솔 목록에서 "버전 표시"를 켜야 실제로 무엇이 남아 있는지 보인다. 여기서 두 가지를 알게 됐다.
- 지운 것처럼 보여도 지워진 게 아니다. 보관이 목적이라면 좋은 일이지만, 용량을 줄이려고 지운 거라면 목적을 달성하지 못한 상태다.
- 삭제 마커 자체도 쌓인다. 원본을 모두 지운 뒤에도 마커만 남아 목록을 채우는 경우가 생긴다. 라이프사이클에서 만료된 삭제 마커를 함께 정리하도록 설정해야 깔끔해진다.
비용 영향
추가 비용은 "이전 버전이 얼마나 쌓이느냐"로 결정된다.
덮어쓰기가 거의 없는 경우 (append-only)
EDI 데이터처럼 한번 올라가면 수정 없이 쌓이는 구조에서는 이전 버전이 거의 생기지 않으므로 추가 비용이 사실상 없다.
주기적으로 덮어쓰는 경우
| 일일 덮어쓰기량 | 이전 버전 보존 30일 | S3 Standard 추가 비용 (월) |
|---|---|---|
| 1GB | 30GB | 약 $0.75 |
| 5GB | 150GB | 약 $3.75 |
| 10GB | 300GB | 약 $7.50 |
금액 자체는 크지 않다. 문제는 정리 정책이 없으면 이 증가가 멈추지 않는다는 점이다. 30일이 아니라 1년이 쌓이면 같은 표의 열두 배가 된다.
비용 절감 방법
라이프사이클 정책으로 이전 버전을 자동 정리한다.
- 이전 버전 30일 후 삭제 → 최대 30일치만 보존
- 이전 버전 30일 후 Glacier Deep Archive 이동 → 비용 1/10 수준
- 만료된 삭제 마커 정리 → 목록만 차지하는 마커 제거
- 불완전한 멀티파트 업로드 정리 → 실패한 업로드 조각이 남아 과금되는 것 방지
마지막 두 항목은 버전 관리와 직접 관련은 없지만, 같은 라이프사이클 규칙에서 함께 정리할 수 있어 이때 같이 넣어두는 편이 좋다.
적용 방법
버전 관리 활성화
- AWS 콘솔에서 S3의 대상 버킷을 열고 "속성(Properties)" 탭으로 이동
- "버킷 버전 관리(Bucket Versioning)"에서 "편집" 클릭
- "활성화(Enable)"를 선택하고 저장
라이프사이클 정책 (이전 버전 자동 정리)
- "관리(Management)" 탭에서 "수명 주기 규칙 생성"
- 설정:
- 규칙 이름:
delete-old-versions - 범위: 버킷의 모든 객체에 적용
- "객체의 이전 버전 영구 삭제" 체크
- 경과 일수: 30
- 보관할 새 버전 수: 1
- 규칙 이름:
복구할 때
복구는 이전 버전을 "되살리는" 게 아니라, 그 버전을 다시 최신 버전으로 올리는 방식이다.
- 덮어쓰기를 되돌릴 때: 이전 버전을 선택해 같은 키로 다시 복사한다. 그러면 그 내용이 최신 버전이 된다
- 삭제를 되돌릴 때: 삭제 마커를 지우면 직전 버전이 다시 최신 버전으로 보인다
한 번쯤 실제로 해보는 게 좋다. 복구 절차를 모르는 백업은 없는 백업과 비슷하다는 걸 EC2 복원 가이드를 정리하면서도 같은 방식으로 확인했다.
버킷별 적용 판단 기준
| 버킷 유형 | 버전 관리 필요성 | 이유 |
|---|---|---|
| 프론트엔드 빌드 배포 | 높음 | 같은 파일명 덮어쓰기 빈번, 배포 실패 시 즉시 롤백 가능 |
| 사용자 데이터 | 높음 | 실수 삭제와 덮어쓰기 복구 |
| 감사 로그 | 높음 | 로그 변조와 삭제 방지 |
| EDI 허브 (append-only) | 낮음 | 매번 다른 파일명으로 쌓이는 구조라 이전 버전이 거의 없음 |
| 임시와 테스트 | 낮음 | 불필요한 비용 발생 |
적용 전 확인
버킷의 데이터 변경 패턴을 먼저 본다.
S3 콘솔 → 대상 버킷 → 지표(Metrics) 탭 → 버킷 지표
→ PutObject 요청 수로 덮어쓰기 빈도 파악
- PutObject가 거의 없으면 바로 적용해도 된다 (비용 영향 없음)
- PutObject가 많으면 라이프사이클 정책을 반드시 함께 설정한다
주의사항
- 버전 관리는 한 번 켜면 "비활성화(Suspended)"만 가능하고 완전히 끌 수 없다
- 비활성화해도 기존 이전 버전은 남아 있다 (수동 또는 라이프사이클로 정리 필요)
- MFA Delete를 추가로 설정하면 버전 삭제 시 MFA 인증을 요구할 수 있다
- 버킷 크기를 볼 때 이전 버전과 삭제 마커가 포함되는지 확인한다. 최신 버전만 보면 실제 과금 대상과 다르다
정리
- 버전 관리는 데이터 보호의 기본이지만, 모든 버킷에 일괄 적용할 필요는 없다
- 이전 버전은 같은 키를 덮어쓰거나 삭제할 때만 생긴다. 쌓이는 방식이 비용을 결정한다
- 삭제해도 용량이 줄지 않는 건 정상 동작이다. 정리는 라이프사이클이 맡는다
- 프론트엔드 빌드, 사용자 데이터, 감사 로그 버킷은 우선 적용 대상이다
배운 점
좋은 기능이라고 전부 켜면 비용이 따라온다. 버전 관리는 분명히 안전장치지만, 같은 키를 덮어쓰지 않는 버킷에서는 켜도 이전 버전이 거의 생기지 않는다. 보호 효과도 비용도 데이터가 쌓이는 방식에 달려 있었다. 그래서 판단 기준을 "중요한가"가 아니라 "덮어쓰는가"로 바꿨다.
켜는 일과 관리하는 일은 한 세트다. 이전 버전을 정리하는 정책까지 정해야 이 작업이 끝난다. 정리 없이 켜두면 몇 달 뒤에 "이 버킷 용량이 왜 이렇지"라는 질문으로 돌아온다. 같은 이유로 S3 퍼블릭 액세스 차단에서도 켠 상태를 유지하는 장치까지 포함해서 작업을 마쳤다.
"지웠다"는 말도 설정에 따라 뜻이 달라진다. 버전 관리를 켠 버킷에서 delete는 감추는 동작에 가깝다. 같은 단어가 환경마다 다른 것을 가리킬 수 있다는 걸, 지표를 볼 때도 ECS StorageWriteBytes 폭증 원인 분석에서 비슷하게 겪었다.
이어 읽기
- S3 버킷 접근 제어 및 Presigned URL 운영 전략: 같은 버킷의 접근 통제 설계
- S3 퍼블릭 액세스 차단 가이드: 데이터 보호의 다른 한 축
- EC2 복원 가이드: AMI + EBS 스냅샷 조합 복원: 복구 절차를 미리 밟아보는 이유