CloudFront 캐시 무효화(Invalidation) 완벽 가이드 — S3 파일 교체 후 즉시 반영하는 방법
S3 버킷에 파일을 덮어썼는데 CloudFront는 여전히 구버전을 서빙하고 있다. 배포 직후 사용자 신고가 들어오고, 콘솔을 열어보면 S3에는 분명 새 파일이 올라가 있다. 이 상황에서 필요한 것이 CloudFront 캐시 무효화(Invalidation)다 — 엣지 로케이션에 남아있는 캐시 객체를 강제로 만료시켜 다음 요청 시 오리진에서 최신 버전을 가져오게 만드는 메커니즘이다.
TL;DR — CloudFront 캐시 무효화 핵심 요약
| 상황 | 권장 방법 | 비용 |
|---|---|---|
| 특정 파일 1~수십 개 교체 | 경로 지정 Invalidation | 월 1,000 경로 무료, 초과 시 유료 |
| 전체 캐시 일괄 초기화 | /* 와일드카드 Invalidation | 1개 경로로 카운트되나 모든 객체 무효화 |
| 배포 파이프라인 자동화 | CLI / SDK Invalidation 호출 | 동일 과금 구조 |
| 근본적 캐시 충돌 방지 | 파일명 버전닝(캐시 버스팅) | 무료 — Invalidation 불필요 |
정가 및 무료 한도는 변경될 수 있으므로 AWS CloudFront 공식 요금 페이지에서 확인하라.
CloudFront 캐시가 동작하는 방식 — 왜 S3를 바꿔도 즉시 반영되지 않는가
CloudFront는 전 세계 엣지 로케이션에 콘텐츠 사본을 저장한다. 사용자 요청이 들어오면 엣지가 먼저 로컬 캐시를 확인하고, 캐시 히트면 오리진(S3)에 전혀 접근하지 않고 응답한다. 캐시 항목은 TTL(Time To Live)이 만료되거나 명시적으로 무효화될 때까지 유지된다.
S3에 파일을 덮어써도 엣지 캐시의 TTL이 남아있는 한 CloudFront는 오리진을 다시 조회하지 않는다. TTL은 오리진의 Cache-Control 헤더 또는 CloudFront 배포 설정의 'Default TTL'로 결정된다. 기본값이 24시간이면 최대 하루 동안 구버전이 서빙될 수 있다.
(캐시 보유)"] Origin["오리진 S3
(최신 파일)"] CacheHit["캐시 히트
구버전 응답"] CacheMiss["캐시 미스
오리진 조회"] Invalidation["Invalidation 요청
캐시 강제 만료"] User -->|"요청"| Edge Edge -->|"TTL 유효"| CacheHit Edge -->|"TTL 만료 또는
Invalidation 후"| CacheMiss CacheMiss -->|"최신 객체 요청"| Origin Origin -->|"새 버전 반환"| Edge Invalidation -->|"캐시 항목 만료"| Edge style CacheHit fill:#4a90d9,color:#fff style CacheMiss fill:#e8a838,color:#fff style Invalidation fill:#d94a4a,color:#fff
- 캐시 히트 경로(파란색): 사용자 요청 → 엣지 로케이션 → 캐시 존재 → 즉시 응답. 오리진 조회 없음.
- 캐시 미스 경로(주황색): TTL 만료 또는 Invalidation 후 첫 요청 → 엣지가 S3에서 최신 객체 가져옴 → 캐시 갱신 → 응답.
- Invalidation 효과: 무효화 요청은 엣지의 캐시 항목을 즉시 만료 상태로 전환한다. 다음 요청이 캐시 미스를 트리거하여 오리진에서 새 버전을 가져온다.
CloudFront 캐시 무효화 — 3가지 실행 방법
방법 1: AWS 콘솔에서 Invalidation 생성
가장 빠르게 확인할 수 있는 방법이다. 배포가 드물고 대상 경로가 명확할 때 적합하다.
- AWS 콘솔 → CloudFront → 해당 배포 선택
- Invalidations 탭 → Create invalidation 클릭
- 무효화할 경로 입력. 예:
/images/banner.jpg또는/static/* - Create invalidation 버튼 클릭 → 상태가 In Progress에서 Completed로 바뀌면 완료
콘솔에서 상태를 새로고침하며 기다리는 것보다 CLI로 폴링하는 편이 훨씬 낫다. 완료까지 보통 수 분이 걸리지만 엣지 로케이션 수와 부하에 따라 달라진다.
방법 2: AWS CLI로 Invalidation 생성 (권장)
배포 파이프라인이나 스크립트에서 호출할 때 사용한다. --distribution-id는 CloudFront 배포 ID(예: E1EXAMPLE)이며 콘솔 또는 아래 CLI로 확인한다.
배포 ID 확인:
aws cloudfront list-distributions \
--query 'DistributionList.Items[*].{Id:Id,Domain:DomainName,Status:Status}' \
--output table
특정 경로 무효화:
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE \
--paths '/images/banner.jpg' '/css/main.css'
전체 캐시 무효화 (/*):
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE \
--paths '/*'
Invalidation 완료까지 대기 (CI/CD 파이프라인에서 유용):
aws cloudfront wait invalidation-completed \
--distribution-id E1EXAMPLE \
--id INVALIDATION_ID
INVALIDATION_ID는 create-invalidation 응답의 Invalidation.Id 값이다. wait 명령은 완료될 때까지 폴링하며 블로킹된다.
🔽 create-invalidation 전체 응답 예시 (클릭하여 펼치기)
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/E1EXAMPLE/invalidation/I1EXAMPLE",
"Invalidation": {
"Id": "I1EXAMPLE",
"Status": "InProgress",
"CreateTime": "2024-01-15T09:00:00.000Z",
"InvalidationBatch": {
"Paths": {
"Quantity": 1,
"Items": [
"/*"
]
},
"CallerReference": "cli-1705312800"
}
}
}
방법 3: Invalidation에 필요한 IAM 권한
CI/CD 파이프라인이나 Lambda 등에서 Invalidation을 호출할 때 최소 권한 원칙을 적용해야 한다.
🔽 최소 권한 IAM 정책 예시 (클릭하여 펼치기)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudfrontInvalidation",
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation",
"cloudfront:GetInvalidation",
"cloudfront:ListInvalidations"
],
"Resource": "arn:aws:cloudfront::123456789012:distribution/E1EXAMPLE"
}
]
}
cloudfront:ListDistributions처럼 목록 조회 액션은 리소스 수준 제한을 지원하지 않아 "Resource": "*"가 필요할 수 있다. AWS Service Authorization Reference에서 각 액션의 리소스 수준 지원 여부를 반드시 확인하라.
Invalidation 상태 모니터링 및 검증
Invalidation을 생성했다고 끝이 아니다. 실제로 엣지에서 새 버전이 서빙되는지 확인해야 한다.
Invalidation 목록 및 상태 확인:
aws cloudfront list-invalidations \
--distribution-id E1EXAMPLE \
--query 'InvalidationList.Items[*].{Id:Id,Status:Status,CreateTime:CreateTime}' \
--output table
특정 Invalidation 상세 조회:
aws cloudfront get-invalidation \
--distribution-id E1EXAMPLE \
--id I1EXAMPLE
curl로 캐시 헤더 직접 확인:
curl -I https://d1example.cloudfront.net/images/banner.jpg
응답 헤더에서 X-Cache: Hit from cloudfront이면 아직 캐시된 버전이고, X-Cache: Miss from cloudfront이면 오리진에서 새로 가져온 것이다. Invalidation 완료 후 첫 요청에서 Miss가 뜨고 이후 Hit로 바뀌는 것이 정상 동작이다.
- InProgress: Invalidation 요청이 접수되어 전파 중. 엣지 로케이션마다 순차적으로 적용된다.
- Completed: 모든 엣지 로케이션에 무효화가 전파 완료. 이후 요청은 오리진에서 최신 버전을 가져온다.
- X-Cache Miss → Hit: 완료 후 첫 요청이 오리진 조회를 트리거하고, 이후 요청은 새 버전이 캐시되어 Hit로 응답한다.
실제 운영에서 자주 겪는 함정 — 잘못된 진단과 실제 원인
Invalidation을 생성했는데도 여전히 구버전이 보인다는 신고가 들어왔다. 콘솔에서 상태는 Completed다. 처음엔 CloudFront 전파 지연을 의심했다.
실제 원인은 달랐다. curl -I로 응답 헤더를 보니 X-Cache: Hit from cloudfront가 아니라 브라우저 자체 캐시에서 서빙되고 있었다. CloudFront는 정상적으로 새 버전을 내려보내고 있었지만, 브라우저가 로컬 캐시를 사용하고 있었던 것이다.
CloudFront Invalidation은 엣지 캐시만 지운다. 브라우저 캐시, CDN 앞단의 다른 프록시, 또는 ISP 캐시는 건드리지 않는다. 사용자 브라우저에서 강제 새로고침(Ctrl+Shift+R)을 해도 동일 증상이 재현된다면 CloudFront 문제가 아니다.
진단 순서가 중요하다. 먼저 curl로 CloudFront 엣지에서 직접 응답을 확인하고, 그 다음 브라우저 캐시를 배제한 뒤, 마지막으로 Invalidation 상태를 점검하라.
또 다른 함정: /*로 전체 무효화를 했는데 특정 경로만 여전히 구버전이다. 이 경우 해당 경로에 별도 캐시 동작(Cache Behavior)이 설정되어 있고, 그 동작에 다른 오리진이나 TTL이 적용되어 있을 가능성을 확인해야 한다. 배포의 Cache Behaviors 탭에서 경로 패턴 매핑을 검토하라.
근본적 해결책 — 캐시 버스팅으로 Invalidation 의존도 줄이기
Invalidation은 응급처치다. 배포할 때마다 Invalidation을 수동으로 실행해야 한다면 파이프라인 설계를 재검토할 시점이다.
파일명에 콘텐츠 해시나 버전을 포함시키는 캐시 버스팅 전략이 근본적 해결책이다.
| 방식 | 예시 | 장점 | 단점 |
|---|---|---|---|
| 파일명 해시 | main.a3f2c1.js | Invalidation 불필요, 무제한 캐시 가능 | 빌드 도구 설정 필요 |
| 쿼리 스트링 | main.js?v=20240115 | 파일명 유지 | CloudFront 기본 설정에서 쿼리 스트링을 캐시 키에 포함해야 함 |
| Invalidation | /* 또는 경로 지정 | 즉시 적용 | 비용 발생, 전파 시간 존재 |
쿼리 스트링을 캐시 키로 사용하려면 CloudFront 배포의 Cache Policy에서 쿼리 스트링을 캐시 키에 포함하도록 설정해야 한다. 기본 Managed Cache Policy 중 일부는 쿼리 스트링을 무시하므로 반드시 확인하라.
CloudFront 캐시 무효화 마무리 및 다음 단계
CloudFront 캐시 무효화는 S3 파일 교체 후 즉시 최신 버전을 서빙해야 할 때 가장 직접적인 해결책이다. CLI의 create-invalidation과 wait invalidation-completed를 CI/CD 파이프라인에 통합하면 배포 자동화가 완성된다. 장기적으로는 파일명 해시 기반 캐시 버스팅으로 전환해 Invalidation 비용과 운영 부담을 줄이는 것이 바람직하다.
다음 단계로 검토할 항목:
- AWS 공식 문서: CloudFront 캐시 무효화
- CloudFront Cache Policy 및 Origin Request Policy 설정 검토
- S3 이벤트 → Lambda → Invalidation 자동화 파이프라인 구성
- CloudFront 액세스 로그 활성화로 캐시 히트율 모니터링
핵심 용어 정리
| 용어 | 설명 |
|---|---|
| Invalidation (무효화) | CloudFront 엣지 로케이션의 캐시 항목을 강제 만료시키는 작업. 다음 요청 시 오리진에서 최신 버전을 가져오게 한다. |
| TTL (Time To Live) | 캐시 항목이 유효한 시간. 만료 후 다음 요청에서 오리진 재조회가 발생한다. |
| 엣지 로케이션 (Edge Location) | CloudFront가 콘텐츠를 캐시하고 사용자에게 서빙하는 전 세계 분산 거점. |
| 캐시 버스팅 (Cache Busting) | 파일명이나 URL에 버전 정보를 포함시켜 브라우저와 CDN이 새 파일을 강제로 가져오게 하는 기법. |
| X-Cache 헤더 | CloudFront 응답 헤더. Hit from cloudfront는 캐시 히트, Miss from cloudfront는 오리진 조회를 의미한다. |
댓글
댓글 쓰기