Amazon S3 심화 정리 4편. S3 복제(CRR·SRR)를 본사·지사 자동 미러링 비유로 풀어 — 복제 전제 조건, 규칙·필터·우선순위, Replication Time Control(15분 SLA), 양방향 복제, SSE-KMS 객체 별도 설정 함정, 기존 객체 복제(Batch Operations), 복제되지 않는 항목까지 친절하게 정리.
이 글은 Amazon S3 심화 정리 시리즈의 네 번째 편입니다. 1편에서 객체 스토리지의 뼈대, 2편에서 보안, 3편에서 성능 최적화까지 잡았다면 — 이번엔 S3 복제(Replication) 차례예요. "버킷 하나에 잘 넣어 뒀는데 또 어딘가로 자동 복사한다고? 왜?" 라는 의문이 가장 먼저 떠오르는 영역입니다.
답은 한 줄로 말하면 — 본사 자료를 다른 도시 지사에도 똑같이 두고 싶을 때, 그리고 그 작업을 사람이 매번 하지 않게 만들고 싶을 때 쓰는 게 S3 복제예요. 이 글은 그 비유를 따라 CRR·SRR·RTC·양방향 S3 복제·기존 객체 일괄 복제·복제되지 않는 항목까지 한 그림으로 묶어 갑니다. 공식 사양이 궁금하면 S3 사용자 가이드의 Replication 단원을 같이 펼쳐 두면 좋아요.
왜 S3 복제가 처음엔 어렵게 느껴질까요
이유는 세 가지예요.
첫째, S3 복제라는 단어가 너무 광범위합니다. "복사해 둔다"는 직관은 누구나 있는데, S3 복제는 그 안에 CRR·SRR·RTC·양방향·교차 계정 같은 하위 개념이 줄지어 있어서 처음 보면 어디서부터 잡아야 할지 막막해요.
둘째, 전제 조건이 의외로 까다롭습니다. 그냥 "복제 켜기" 버튼만 누르면 될 것 같은데, 실제로는 소스·대상 버전 관리 활성화 + IAM 역할 + 대상 버킷 권한까지 챙겨야 해요. 한 가지만 빠져도 동작 안 합니다.
셋째, "복제되는 것 / 복제 안 되는 것"의 구분이 시험에 자주 나옵니다. 라이프사이클 동작은 복제될까? 복제된 객체가 또 복제될까? 버전 ID 지정 삭제는 복제될까? — 이런 함정 질문들이 좁쌀처럼 깔려 있어요.
해결법은 한 가지예요. S3 복제를 "본사와 지사를 같은 자료로 묶는 자동 미러링 시스템" 으로 비유로 잡고, 각 기능을 "누가 / 어디로 / 얼마나 빨리 / 무엇을" 의 네 축으로 풀면 갑자기 그림이 깔끔해집니다. 이 글은 그 축을 따라 처음부터 가요.
S3 복제가 도대체 어떤 기능인가요
S3 복제(Replication)는 한 줄로 정리하면 — 소스 버킷에 새로 들어온 객체를 대상 버킷으로 자동 비동기 복사하는 기능이에요.
회사 비유로 풀면 이런 그림이에요. 본사 자료실(소스 버킷)에 누군가 새 자료를 꽂으면, 지정된 직원(IAM 역할을 가진)이 그 자료를 자동으로 복사해서 지사 자료실(대상 버킷)에 똑같이 꽂아 줍니다. 사람이 매번 "이거 지사에도 보내 주세요" 하지 않아도 되는 거예요.
S3 복제를 왜 쓰는지 정리하면:
- 재해 복구(DR) — 본사가 화재로 통째로 사라져도 지사에 사본이 살아 있음
- 규정 준수 — 데이터 주권 법령이 "이 자료는 한국 안에 있어야 한다" 식으로 요구할 때
- 지연 시간 최소화 — 전 세계 사용자에게 가까운 리전에서 데이터 제공
- 워크로드 분리 — 프로덕션 자료를 분석·테스트 환경에 떼어 둠
- 로그 집계 — 여러 버킷의 로그를 한 곳에 모음
여기서 시험 함정이 하나 있어요. S3 복제는 비동기(Asynchronous) 입니다. 소스에 객체가 들어가는 즉시 대상에 나타나는 게 아니에요. 약간의 지연(보통 수 초~수 분)이 있고, 이 지연을 99.99% 15분 안에 보장하려면 별도로 Replication Time Control(RTC) 을 켜야 합니다. RTC는 뒤에서 자세히 풀어 갈게요.
S3 복제 전제 조건 — 출입증부터 챙기기
S3 복제를 켜기 전에 다음 조건이 모두 갖춰져야 해요. 하나라도 빠지면 동작 안 합니다.
- 소스 버킷 버전 관리 활성화 — 필수
- 대상 버킷 버전 관리 활성화 — 필수 (이게 자주 빠집니다)
- 복제용 IAM 역할 — S3 서비스가 객체를 읽고 대상에 쓸 수 있는 권한
- (교차 계정인 경우) 대상 버킷 정책에서 소스 IAM 역할 허용
- (KMS 암호화인 경우) 양쪽 KMS 키 권한 설정
회사 비유로 — 본사·지사 양쪽이 모두 버전 보관 시스템을 갖추고 있어야 하고, 복제를 대신 해 주는 직원에게는 본사 출입증 + 지사 출입증이 모두 있어야 하는 식이에요. 한쪽만 있으면 자료를 가져갈 수는 있어도 꽂을 수가 없죠.
여기서 시험 함정이 하나 있어요. 버전 관리는 "양쪽 모두" 켜야 합니다. 소스만 켜면 안 돼요. 시험 보기에서 "소스 버킷 버전 관리만 활성화하면 된다"는 문장이 나오면 함정입니다.
CRR — 본사와 다른 도시 지사 사이
CRR(Cross-Region Replication) 은 서로 다른 AWS 리전 사이의 복제예요. 예를 들어 us-east-1(버지니아) 버킷의 자료를 ap-northeast-2(서울) 버킷으로 자동 복사하는 식.
회사 비유로 — 본사(서울) 자료를 다른 도시 지사(부산) 에 자동 미러링하는 그림이에요. 거리가 멀어서 네트워크 비용도 더 들고 도착도 좀 더 걸리지만, 본사 도시 자체에 재난이 와도 부산 지사에는 자료가 살아 있어요.
CRR을 언제 쓰느냐:
- 재해 복구 — 한 리전이 통째로 다운돼도 다른 리전에서 서비스 지속
- 데이터 주권 — "이 자료는 EU 안에 있어야 한다" 같은 법적 요구
- 글로벌 사용자 지연 최소화 — 미국 사용자에게는 us-east-1, 한국 사용자에게는 ap-northeast-2에서 응답
- 데이터 분석 분리 — 분석 워크로드를 다른 리전에 격리
CRR 설정의 핵심은 소스 리전 버전 관리 + 대상 리전 버전 관리 + IAM 역할 + 복제 규칙 네 가지예요.
# 1. 소스 버킷 버전 관리 활성화
aws s3api put-bucket-versioning \
--bucket source-bucket \
--versioning-configuration Status=Enabled
# 2. 대상 버킷 버전 관리 활성화 (다른 리전)
aws s3api put-bucket-versioning \
--bucket destination-bucket \
--region ap-northeast-2 \
--versioning-configuration Status=Enabled
# 3. 복제 IAM 역할 생성 (S3 서비스가 위임받을 수 있는 신뢰 정책)
cat > replication-trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "s3.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role \
--role-name S3ReplicationRole \
--assume-role-policy-document file://replication-trust-policy.json
# 4. 역할에 권한 정책 부여 (소스에서 읽고 대상에 쓰기)
cat > replication-permissions.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging"
],
"Resource": "arn:aws:s3:::source-bucket/*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::source-bucket"
},
{
"Effect": "Allow",
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags"
],
"Resource": "arn:aws:s3:::destination-bucket/*"
}
]
}
EOF
aws iam put-role-policy \
--role-name S3ReplicationRole \
--policy-name S3ReplicationPolicy \
--policy-document file://replication-permissions.json
# 5. CRR 복제 규칙 적용
aws s3api put-bucket-replication \
--bucket source-bucket \
--replication-configuration '{
"Role": "arn:aws:iam::123456789012:role/S3ReplicationRole",
"Rules": [
{
"ID": "CrossRegionReplication",
"Status": "Enabled",
"Filter": {"Prefix": ""},
"Destination": {
"Bucket": "arn:aws:s3:::destination-bucket",
"StorageClass": "STANDARD"
},
"DeleteMarkerReplication": {"Status": "Enabled"}
}
]
}'
권한 정책의 액션이 두 묶음으로 갈리는 게 핵심이에요. **소스에서는 GetForReplication 류로 읽고, 대상에서는 Replicate** 류로 씁니다. 이 둘을 다 갖춰야 직원(IAM 역할)이 본사·지사 양쪽을 오갈 수 있어요.
SRR — 같은 도시 두 사옥 사이
SRR(Same-Region Replication) 은 같은 AWS 리전 안에서 다른 버킷으로 복제하는 거예요. 예를 들어 ap-northeast-2 안의 app-logs-prod 버킷에서 같은 리전의 log-aggregation 버킷으로.
회사 비유로 — 같은 서울 안의 두 사옥 사이를 자동 미러링하는 그림이에요. 거리가 가까워서 네트워크 비용·지연이 작고, 리전 단위 재해는 여전히 한 번에 당하지만 버킷 단위 운영 분리에는 충분해요.
SRR을 언제 쓰느냐:
- 로그 집계 — 여러 애플리케이션 버킷의 로그를 하나의 분석 버킷으로
- 프로덕션/테스트 환경 분리 — 프로덕션 자료의 사본을 테스트 환경 버킷에
- 법적 준수상 동일 리전 내 다른 계정으로 복제
- 데이터 공유 — 여러 팀이 같은 자료를 사용할 때
# SRR — 동일 리전이라 region 옵션 불필요
aws s3api put-bucket-replication \
--bucket source-bucket \
--replication-configuration '{
"Role": "arn:aws:iam::123456789012:role/S3ReplicationRole",
"Rules": [
{
"ID": "SameRegionReplication",
"Status": "Enabled",
"Filter": {"Prefix": "logs/"},
"Destination": {
"Bucket": "arn:aws:s3:::log-aggregation-bucket"
}
}
]
}'
CRR과 SRR의 비교를 표로 보면:
| 항목 | CRR | SRR |
|---|---|---|
| 리전 | 서로 다른 리전 | 동일 리전 |
| 주요 목적 | 재해 복구, 글로벌 지연 최소화 | 로그 집계, 환경 분리 |
| 데이터 전송 비용 | 리전 간 전송 비용 발생 | 상대적으로 낮음 |
| 버전 관리 필요 | 양쪽 필수 | 양쪽 필수 |
| IAM 역할 필요 | 필수 | 필수 |
여기서 시험 함정이 하나 있어요. CRR이든 SRR이든 양쪽 버전 관리는 똑같이 필수예요. 보기에서 "SRR은 버전 관리 없이도 가능"이라고 나오면 함정입니다.
복제 규칙 — 무엇을 / 어디로 명세서
복제를 켤 때 작성하는 게 복제 규칙(Replication Rule) 이에요. 회사 비유로 — "어떤 자료를 / 어떤 우선순위로 / 어디로 / 어느 등급으로 보낼지" 를 적은 명세서입니다.
규칙 하나에는 다음 항목이 들어가요.
- ID — 규칙 이름
- Status — Enabled / Disabled
- Filter — 어떤 객체를 복제할지 (접두사 / 태그 / 둘 다)
- Destination — 어느 버킷으로, 어느 스토리지 클래스로
- Priority — 여러 규칙이 겹칠 때 우선순위
- DeleteMarkerReplication — 삭제 마커도 복제할지
- (선택) ReplicationTime — RTC 활성화
- (선택) Metrics — 복제 메트릭 활성화
- (선택) EncryptionConfiguration — KMS 키 지정
- (선택) ExistingObjectReplication — 기존 객체 복제 (Batch와 함께)
필터 — 무엇을 복제할까
필터에는 세 가지 형태가 있어요.
1) 접두사 기반 — 특정 폴더(접두사) 아래 객체만:
{ "Filter": { "Prefix": "production/" } }
2) 태그 기반 — 특정 태그가 붙은 객체만:
{
"Filter": {
"Tag": { "Key": "Environment", "Value": "Production" }
}
}
3) 접두사 + 태그 조합 — 둘을 AND로 묶을 때:
{
"Filter": {
"And": {
"Prefix": "data/",
"Tags": [
{"Key": "Replicate", "Value": "true"},
{"Key": "Department", "Value": "Finance"}
]
}
}
}
여기서 시험 함정이 하나 있어요. 여러 조건을 묶을 때는 반드시 And 블록 안에 넣어야 합니다. Filter 바로 아래에 Prefix와 Tag를 동시에 두면 문법 오류예요.
우선순위 — 여러 규칙이 겹칠 때
한 버킷에 여러 복제 규칙을 둘 수 있는데, 객체가 두 규칙의 필터에 동시에 매칭되면 Priority 숫자가 큰 규칙이 이깁니다. 예를 들어 production/ 접두사 규칙(Priority 10)과 production/secret/ 접두사 규칙(Priority 20)이 있으면, production/secret/foo.txt는 Priority 20 규칙을 따라요.
회사 비유로 — 같은 자료에 두 명세서가 겹치면 더 중요한 명세서가 적용되는 식. 비밀 자료는 더 엄격한 규칙으로, 일반 자료는 기본 규칙으로 가는 거예요.
스토리지 클래스 변경
대상에서는 다른 스토리지 클래스를 쓸 수 있어요. 본사는 Standard로 빠르게 두고, 지사 사본은 비용 절감을 위해 Standard-IA나 Glacier로 두는 패턴.
{
"Destination": {
"Bucket": "arn:aws:s3:::destination-bucket",
"StorageClass": "STANDARD_IA"
}
}
회사 비유로 — 본사에는 책상 옆 자주 꺼내는 자리에 두고, 지사에는 창고 깊은 곳에 두는 거예요. 어차피 지사는 비상용이니까요.
삭제 마커 복제
DeleteMarkerReplication이 Enabled면 — 소스에서 객체를 (버전 ID 없이) 삭제해 삭제 마커가 생기면, 그 삭제 마커도 대상에 복제됩니다.
{ "DeleteMarkerReplication": { "Status": "Enabled" } }
여기서 시험 함정이 하나 있어요. 버전 ID를 지정한 진짜 삭제(영구 삭제)는 복제되지 않습니다. 이건 악의적 또는 실수 삭제 방지를 위한 의도적 설계예요. 누가 소스에서 특정 버전을 영구 삭제해도 대상에는 그 버전이 살아 있어요.
회사 비유로 — 본사 사람이 "이 자료 영구 폐기" 라고 표시한 건 지사로 안 넘어갑니다. 지사는 지사대로 백업 사본을 그대로 갖고 있어요. 누군가 본사 자료를 통째로 망가뜨려도 지사는 안전한 거죠.
RTC — 15분 안에 도착 보장하는 특송 서비스
기본 복제는 비동기라서 객체가 대상에 도착하는 시간이 들쭉날쭉해요. 보통은 수 초~수 분이지만, 트래픽이 몰리면 더 걸릴 수도 있어요.
이걸 SLA로 묶어 주는 게 RTC(Replication Time Control) 입니다. 회사 비유로 — 일반 택배가 아니라 "15분 도착 보장 특송 서비스" 를 끼우는 거예요. 추가 요금을 내고 약속을 받는 식.
RTC가 보장하는 건:
- 객체의 99.99%를 15분 이내에 복제
- 도달하지 못한 1%에 대한 시각화 (메트릭·이벤트)
- 복제 메트릭 자동 활성화 (CloudWatch에서 확인)
언제 쓰느냐:
- 비즈니스 크리티컬 데이터 — 주문·결제처럼 잠깐의 지연도 위험한 자료
- 규정 준수상 복제 시간 증명 필요 — "15분 안에 백업됐다" 는 SLA 문서를 외부에 제시해야 할 때
- 재해 복구 RPO 최소화 — 사고 났을 때 잃는 데이터 양을 15분 분량 이하로
aws s3api put-bucket-replication \
--bucket source-bucket \
--replication-configuration '{
"Role": "arn:aws:iam::123456789012:role/S3ReplicationRole",
"Rules": [
{
"ID": "ReplicationWithRTC",
"Status": "Enabled",
"Filter": {"Prefix": ""},
"Destination": {
"Bucket": "arn:aws:s3:::destination-bucket",
"ReplicationTime": {
"Status": "Enabled",
"Time": {"Minutes": 15}
},
"Metrics": {
"Status": "Enabled",
"EventThreshold": {"Minutes": 15}
}
}
}
]
}'
여기서 시험 함정이 하나 있어요. RTC는 추가 요금이 발생합니다. GB당 별도 요금이 붙어요. 그리고 RTC를 켜면 메트릭이 자동으로 함께 켜집니다. "RTC만 켜고 메트릭은 안 켜도 된다"는 보기는 함정이에요. RTC 자체에 메트릭이 묶여 있어요.
양방향 복제 — 본사·지사가 서로 동기화
지금까지는 "소스 → 대상" 한 방향이었는데, 양방향 복제는 두 버킷이 서로를 미러링하는 그림이에요. 본사가 지사로, 지사가 본사로.
회사 비유로 — 본사·지사가 같은 등급의 거점이라서 양쪽 모두에서 새 자료가 들어올 수 있고, 어느 쪽에서 만들든 다른 쪽에 즉시 반영되는 식이에요.
설정은 단순해요. 각 버킷에 서로를 향한 복제 규칙을 따로 만들면 됩니다.
# 버킷 A → 버킷 B 복제
aws s3api put-bucket-replication \
--bucket bucket-a \
--replication-configuration '{
"Role": "arn:aws:iam::123456789012:role/S3ReplicationRole",
"Rules": [{
"ID": "AtoB", "Status": "Enabled", "Filter": {"Prefix": ""},
"Destination": {"Bucket": "arn:aws:s3:::bucket-b"}
}]
}'
# 버킷 B → 버킷 A 복제
aws s3api put-bucket-replication \
--bucket bucket-b \
--replication-configuration '{
"Role": "arn:aws:iam::123456789012:role/S3ReplicationRole",
"Rules": [{
"ID": "BtoA", "Status": "Enabled", "Filter": {"Prefix": ""},
"Destination": {"Bucket": "arn:aws:s3:::bucket-a"}
}]
}'
여기서 시험 함정이 하나 있어요. 무한 루프가 안 생기느냐 — 안 생깁니다. S3는 이미 복제된 객체를 다시 복제하지 않아요. 객체 메타데이터에 "이건 다른 곳에서 복제돼 온 것"이라는 표식이 붙고, 그 표식이 있으면 두 번째 복제는 건너뜁니다. 그래서 양방향이라도 같은 객체가 무한히 핑퐁 치지 않아요.
SSE-KMS 객체 복제 — 별도 설정이 필요한 함정
이게 시험과 실무 모두에서 가장 자주 헛걸음하는 영역이에요. SSE-KMS로 암호화된 객체는 기본 복제 설정으로는 복제되지 않습니다. 별도로 켜 줘야 해요.
이유를 풀면 — KMS 키는 리전별 리소스라서 소스 리전 KMS 키로 암호화된 객체를 그냥 다른 리전으로 옮길 수 없어요. 대상 리전의 KMS 키로 다시 암호화해 줘야 하고, 그러려면 복제 설정에 양쪽 키를 모두 알려 줘야 합니다.
회사 비유로 — 본사 자료가 본사 전용 금고 열쇠로 잠겨 있다면, 지사로 그냥 옮기면 지사 직원이 못 열어요. 지사 전용 금고 열쇠로 다시 잠가서 옮겨야 하고, 그러려면 복제 직원에게 본사·지사 양쪽 금고 열쇠 사용 권한이 있어야 합니다.
설정은 두 가지를 함께 해야 해요.
1) 복제 규칙에 KMS 설정 추가:
{
"SourceSelectionCriteria": {
"SseKmsEncryptedObjects": { "Status": "Enabled" }
},
"Destination": {
"Bucket": "arn:aws:s3:::destination-bucket",
"EncryptionConfiguration": {
"ReplicaKmsKeyID": "arn:aws:kms:us-west-2:123456789012:key/destination-key-id"
}
}
}
SourceSelectionCriteria.SseKmsEncryptedObjects = Enabled — 이게 "KMS로 암호화된 객체도 복제 대상에 포함"이라는 신호고, EncryptionConfiguration.ReplicaKmsKeyID 가 "복제본은 이 키로 다시 암호화" 라는 지정이에요.
2) IAM 역할에 KMS 권한 추가:
복제 IAM 역할이 소스 KMS 키 Decrypt 권한과 대상 KMS 키 Encrypt/GenerateDataKey 권한을 모두 가져야 해요. 이게 빠지면 설정은 다 했는데 복제만 조용히 실패합니다.
여기서 시험 함정이 하나 있어요. SSE-KMS 객체는 별도 설정 안 하면 복제 안 됩니다. "S3 복제는 모든 객체를 자동으로 복제한다"는 보기는 함정이에요. SSE-S3·평문 객체는 자동이지만 SSE-KMS는 명시 설정 필요예요.
기존 객체 복제 — Batch Operations Replicate
여기가 처음 보는 분이 가장 많이 당황하는 부분이에요. 복제 규칙은 "규칙 설정 이후 들어오는 새 객체"에만 적용됩니다. 이미 버킷에 들어 있던 기존 객체는 자동으로 복제되지 않아요.
회사 비유로 — 오늘부터 본사 ↔ 지사 자동 미러링을 켰다고 해도, 어제까지 본사에 쌓여 있던 자료는 그대로 본사에만 있어요. 그걸 지사로 옮기려면 별도로 한 번 일괄 작업을 돌려 줘야 합니다.
이때 쓰는 게 S3 Batch Operations의 Replicate 작업이에요. Batch Operations는 큰 객체 묶음에 대해 일괄 작업(복사·복제·태깅·복원·Lambda 호출 등)을 돌려 주는 기능이고, 그중 S3ReplicateObject 작업이 기존 객체를 복제 규칙에 따라 한 번 복제해 줘요.
aws s3control create-job \
--account-id 123456789012 \
--operation '{ "S3ReplicateObject": {} }' \
--manifest-generator '{
"S3JobManifestGenerator": {
"ExpectedBucketOwner": "123456789012",
"SourceBucket": "arn:aws:s3:::source-bucket",
"EnableManifestOutput": false,
"Filter": {
"EligibleForReplication": true,
"ObjectReplicationStatuses": ["NONE", "FAILED"]
}
}
}' \
--report '{
"Bucket": "arn:aws:s3:::reports-bucket",
"Format": "Report_CSV_20180820",
"Enabled": true,
"ReportScope": "AllTasks"
}' \
--priority 1 \
--role-arn arn:aws:iam::123456789012:role/S3BatchOpsRole
핵심은 두 부분이에요.
Filter.EligibleForReplication: true— "복제 규칙에 매칭되는 객체만 골라라"ObjectReplicationStatuses: ["NONE", "FAILED"]— "아직 복제 안 됐거나 실패한 것만 골라라"
콘솔에서 복제 규칙을 처음 만들 때 "기존 객체도 복제할까요?" 라는 안내가 뜨고, 거기서 Yes를 누르면 S3가 자동으로 Batch Operations 작업을 만들어 줍니다. CLI로 할 거면 위처럼 직접 만들면 돼요.
여기서 시험 함정이 하나 있어요. ExistingObjectReplication 설정만 켰다고 해서 기존 객체가 자동으로 복제되는 게 아닙니다. 이 옵션은 Batch Operations와 함께 동작해요. 단독으로 의미가 없어요. "ExistingObjectReplication만 Enabled로 두면 기존 객체가 복제된다"는 보기는 함정이에요.
교차 계정 복제 — 다른 회사 사옥으로 보내기
복제 대상이 같은 AWS 계정이 아니라 다른 AWS 계정의 버킷일 수도 있어요. 백업 전용 계정, 파트너사 공유 계정, 보안 감사 계정 같은 자리에 자주 씁니다.
회사 비유로 — 같은 그룹 내 다른 계열사 사옥으로 자료를 자동 미러링하는 그림이에요. 출입증(IAM 역할) 이 자기 계정에서 발급한 것만으로는 다른 계정 사옥에 못 들어가니까, 다른 계정 사옥에서도 "이 출입증 가진 사람은 들여보내라" 라는 정책을 따로 걸어 줘야 해요.
설정은 두 곳에서 합니다.
소스 계정 쪽 — 평소처럼 복제 IAM 역할 + 복제 규칙을 만들고요.
대상 계정 쪽 — 대상 버킷 정책에서 소스 계정의 IAM 역할에게 복제 액션을 허용해 줘요.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReplication",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SOURCE_ACCOUNT_ID:role/S3ReplicationRole"
},
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
"s3:GetBucketVersioning",
"s3:PutBucketVersioning"
],
"Resource": [
"arn:aws:s3:::destination-bucket",
"arn:aws:s3:::destination-bucket/*"
]
}
]
}
여기서 시험 함정이 하나 있어요. 교차 계정 복제는 대상 버킷 정책 없이는 동작하지 않습니다. "소스 IAM 역할만 잘 만들면 된다"는 보기는 함정이에요. 양쪽이 손을 맞잡아야 해요.
복제 상태 확인 — 잘 가고 있는지 보는 법
복제는 비동기라서 "지금 어디까지 도착했지?" 가 자주 궁금해집니다. S3는 객체마다 ReplicationStatus 필드를 헤더에 붙여 줘요.
| 상태 | 의미 |
|---|---|
PENDING | 복제 대기 또는 진행 중 |
COMPLETED | 복제 완료 |
FAILED | 복제 실패 |
REPLICA | 대상 버킷에서 본 복제된 객체 |
NONE | 복제 대상이 아님 (필터 미매칭 등) |
aws s3api head-object \
--bucket source-bucket \
--key file.txt \
--query 'ReplicationStatus'
대량 객체의 복제 상태를 한 번에 보려면 S3 Inventory에 ReplicationStatus 필드를 포함해 일별 리포트를 받는 패턴이 표준이에요. 실패가 많으면 IAM 권한·KMS 권한·대상 버킷 정책을 다시 점검합니다.
복제되지 않는 항목 — 함정 모음
이 단원에서 시험에 가장 자주 나오는 영역이에요. 처음 한 번에 외우기는 어려워서, "이건 복제 안 된다" 는 목록을 따로 정리해 두는 게 좋아요.
- 복제 규칙 설정 이전에 들어 있던 기존 객체 — Batch Operations로 별도 처리
- 버전 ID를 지정한 영구 삭제 — 악의·실수 삭제 방지 (삭제 마커는 옵션으로 복제 가능)
- 이미 복제된 객체의 재복제 — 무한 루프 방지
- 라이프사이클 동작 자체 — 소스에서 라이프사이클로 클래스가 바뀌어도 그 동작이 대상에 그대로 옮겨지지 않음. 대상은 자기 라이프사이클 정책을 따로 걸어야 함
- SSE-C(고객 제공 키) 암호화 객체 — 지원 X
- (별도 설정 없이) SSE-KMS 객체 —
SourceSelectionCriteria+ KMS 키 + IAM 권한 모두 갖춰야 복제됨 - Glacier·Deep Archive 클래스의 객체 — 일반적으로 복제 대상 아님 (복원 후 가능)
여기서 시험 함정이 하나 있어요. 라이프사이클은 복제되지 않는다 는 게 자주 헷갈려요. "소스에서 30일 뒤 IA로 가는 라이프사이클을 걸면 대상도 자동으로 따라간다"는 보기는 함정입니다. 라이프사이클은 각 버킷에 따로 걸어야 하고, 복제로 따라가지 않아요. 이 점이 라이프사이클(5편 주제)과 복제의 가장 큰 경계선이에요.
복제 메트릭과 이벤트 — 사고 났을 때 알아채기
복제가 조용히 실패하면 무서운 일이에요. "당연히 복제됐을 줄 알았는데 1년 뒤에 복구하려니 비어 있더라" 같은 사고가 실제 일어납니다. 그래서 메트릭과 이벤트를 함께 켜는 게 운영의 표준이에요.
켤 수 있는 것:
- CloudWatch 메트릭 —
ReplicationLatency,BytesPendingReplication,OperationsPendingReplication,OperationsFailedReplication - EventBridge 이벤트 — 복제 실패 시 즉시 알림
- S3 Inventory — 일별로 복제 상태 일괄 점검
# 복제 메트릭 조회
aws cloudwatch get-metric-statistics \
--namespace AWS/S3 \
--metric-name ReplicationLatency \
--dimensions Name=SourceBucket,Value=source-bucket \
Name=DestinationBucket,Value=destination-bucket \
Name=RuleId,Value=ReplicationRule \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-02T00:00:00Z \
--period 3600 \
--statistics Average
# 복제 실패 이벤트 → EventBridge
aws s3api put-bucket-notification-configuration \
--bucket source-bucket \
--notification-configuration '{
"EventBridgeConfiguration": {}
}'
회사 비유로 — 본사 ↔ 지사 자동 운송 시스템을 운영하면 "오늘 몇 박스가 안 도착했지?" 를 매일 점검해야 해요. 메트릭·이벤트·인벤토리 셋이 그 점검판 역할이에요.
비용 — S3 복제는 공짜가 아니에요
S3 복제를 켜면 다음 비용이 함께 들어와요.
- 대상 버킷의 저장 비용 — 사본도 저장량이 GB당 청구됨 (소스의 두 배 저장 비용)
- 데이터 전송 비용 — CRR은 리전 간 전송이라 GB당 추가 요금. SRR은 같은 리전이라 일반적으로 더 낮음
- API 요청 비용 —
PUT,Replicate*요청 비용 - (RTC 사용 시) RTC 데이터 전송 추가 요금
- (SSE-KMS 사용 시) KMS 호출 비용
여기서 시험 함정이 하나 있어요. "복제를 켜면 저장 비용이 두 배가 된다" 는 직관 — 소스에 GB당 가격 + 대상에 GB당 가격이 모두 청구되니까요. "복제는 단순히 백업이라 비용이 작다"는 보기는 함정이에요. 정확히는 사본 저장량 + 전송량이 추가됩니다.
비용을 통제하는 패턴 두 가지:
- 대상 스토리지 클래스를 더 저렴한 등급으로 — 본사 Standard, 지사 Standard-IA 또는 Glacier
- 필터로 복제 범위 좁히기 — 모든 객체가 아니라 진짜 백업이 필요한 접두사·태그만
한 번에 정리하는 압축 노트
여기까지가 4편의 핵심이에요. 시험 직전이나 실무에서 헷갈릴 때 펼쳐 볼 수 있게 압축 노트로 마무리할게요.
- 복제 = 소스 버킷 → 대상 버킷 자동 비동기 복사, 본사·지사 미러링 비유
- CRR = 다른 리전 (재해 복구·글로벌 지연 최소화), SRR = 같은 리전 (로그 집계·환경 분리)
- 전제 조건 — 소스·대상 양쪽 버전 관리 활성화 필수 + 복제 IAM 역할
- 복제는 비동기. SLA 필요하면 RTC 별도 활성화
- RTC = 99.99% 객체를 15분 이내 복제 보장, 메트릭 자동 동반, 추가 요금
- 복제 규칙 필터 — 접두사 / 태그 /
And로 둘 조합. 단독으로 두 키 동시 사용 X - 규칙 여럿이 겹치면
Priority큰 쪽이 이김 - 대상에서 다른 스토리지 클래스 사용 가능 (Standard → Standard-IA·Glacier 등)
- 삭제 마커 복제는 옵션, 버전 ID 지정 영구 삭제는 복제 X (악의·실수 삭제 방지)
- 양방향 복제 = 양쪽에 서로 향한 규칙 따로 만들기, 무한 루프 안 생김(이미 복제된 객체 재복제 X)
- SSE-KMS 객체는 별도 설정 필수 —
SourceSelectionCriteria+ 대상 KMS 키 + IAM에 KMS Decrypt/Encrypt 권한 - SSE-C 객체는 복제 지원 X
- 규칙 설정 이전 기존 객체는 자동 복제 X — S3 Batch Operations Replicate로 별도 일괄 처리
ExistingObjectReplication옵션은 Batch와 함께 동작, 단독으로 의미 없음- 교차 계정 복제 — 소스 IAM 역할 + 대상 버킷 정책에 소스 역할 허용까지 둘 다 필요
- 라이프사이클 동작은 복제되지 않음 — 각 버킷에 라이프사이클 따로 설정
ReplicationStatus—PENDING/COMPLETED/FAILED/REPLICA/NONE- 운영 점검 = CloudWatch 메트릭 + EventBridge 이벤트 + S3 Inventory 조합
- 비용 = 대상 저장량 + 전송량 + API 요청 + (RTC·KMS 시 추가). 사본도 GB당 과금
다음 글(5편)에서는 S3 라이프사이클(Lifecycle) 정책을 풀어 갑니다. 객체를 시간에 따라 자동으로 더 저렴한 스토리지 클래스로 옮기거나 삭제하는 규칙이에요. 이번 글에서 "라이프사이클은 S3 복제로 따라가지 않는다" 라고 짚어 둔 그 라이프사이클을 직접 들여다봐요. 회사 자료의 "창고 이전 일정표" 비유로 풀면서, 클래스 전환·만료·미완료 멀티파트 정리·버전별 보관 기간 같은 함정도 한꺼번에 잡아 갑시다.
시리즈 다른 편
같은 시리즈의 다른 글들도 같은 친절 톤으로 묶어 정리되어 있어요.
- 1편 — 기초
- 2편 — 보안
- 3편 — 성능 최적화
- 4편 — 복제 (현재 글)
- 5편 — 라이프사이클
- 6편 — 고급 기능
- 7편 — AWS 통합 (완)