들어가며
운영 중인 서비스의 CloudFront 설정을 바꿔야 할 때 "혹시 끊기지 않을까"라는 걱정이 먼저 든다. 문서에는 무중단이라고 적혀 있지만, 그 말이 우리 변경에도 해당하는지는 다른 문제다.
이번에 SPA fallback 방식을 바꾸면서 이걸 직접 확인했다. 결론부터 말하면 끊기지 않았는데, 중요한 건 "CloudFront라서 안전했다"가 아니라 우리가 한 변경이 안전한 종류였기 때문이었다.
실제 사례: SPA fallback 방식 전환
기존에는 CloudFront의 Custom Error Response(403을 /index.html로)로 SPA 라우팅을 처리하고 있었다. 멀티 앱 구조로 가면서 CloudFront Function 기반의 경로별 fallback으로 바꿔야 했다.
변경 내용은 두 가지였다.
- Custom Error Response (403 →
/index.html) 제거 - CloudFront Function (경로별 index.html 분기) 추가
둘을 동시에 적용하는 셈인데, 전환 중에 어느 쪽도 동작하지 않는 순간이 있으면 사용자에게 에러가 그대로 노출된다.
CloudFront 배포 업데이트의 동작 방식
CloudFront는 전 세계 수백 개의 엣지 로케이션에서 동작한다. 배포 설정을 바꾸면 모든 엣지에 새 설정을 전파해야 하는데, 이 과정이 한 번에 일어나지 않는다.
[업데이트 시작 - InProgress]
서울 엣지 → 기존 설정으로 서빙 중
도쿄 엣지 → 기존 설정으로 서빙 중
싱가포르 엣지 → 기존 설정으로 서빙 중
[전파 중 (3~10분)]
서울 엣지 → 새 설정 적용 완료
도쿄 엣지 → 아직 기존 설정
싱가포르 엣지 → 아직 기존 설정
[전파 완료 - Deployed]
서울 엣지 → 새 설정
도쿄 엣지 → 새 설정
싱가포르 엣지 → 새 설정
각 엣지는 독립적으로 업데이트된다. 아직 반영되지 않은 엣지는 기존 설정으로 계속 서빙하고, 반영된 엣지는 새 설정으로 서빙한다. 어느 시점에도 "설정 없음" 상태는 없다.
여기서 오해하기 쉬운 부분이 있다. 무중단이 보장하는 건 "요청이 처리된다"까지다. 무엇으로 처리되는지는 보장하지 않는다. 전환 기간 동안 같은 사용자가 새로고침만 해도 다른 엣지에 붙어 다른 설정으로 처리될 수 있다.
우리 사례에서 왜 안전했는가
전파 중에 사용자가 접속하면 두 경우가 생긴다.
1. 이미 새 설정이 적용된 엣지
- CloudFront Function이
/mypage/profile을/index.html로 rewrite - S3에서 index.html 반환, 정상
2. 아직 기존 설정인 엣지
- S3에
/mypage/profile파일이 없으므로 403 발생 - Custom Error Response가 403을
/index.html로 처리 - S3에서 index.html 반환, 정상
어느 쪽이든 결과가 같다. 두 설정이 같은 결과를 만들기 때문에, 어느 엣지에 붙든 사용자는 차이를 느끼지 못했다.
안전한 변경과 그렇지 않은 변경
같은 CloudFront 업데이트라도 성격이 다르다. 기준은 하나다. 전환 기간 동안 두 설정이 공존해도 괜찮은가.
| 변경 유형 | 전환 중 상태 | 판단 |
|---|---|---|
| Custom Error Response → Function (같은 결과) | 어느 쪽이든 index.html | 안전 |
| 캐시 정책, TTL 조정 | 캐시 적중률만 달라짐 | 대체로 안전 |
| Origin을 다른 서버로 교체 | 기존 Origin이 살아 있어야 함 | 순서가 중요 |
| SSL 인증서 교체 | 새 인증서가 먼저 준비돼야 함 | 순서가 중요 |
| Behavior 경로 패턴 대폭 변경 | 경로에 따라 다른 동작 | 겹침 확인 필요 |
Origin 교체가 대표적인 위험 사례다. 새 Origin을 가리키도록 바꾸는 동안, 아직 전파되지 않은 엣지는 여전히 기존 Origin으로 요청을 보낸다. 이때 기존 Origin을 미리 내려버렸다면 그 엣지의 사용자만 에러를 본다. 전파가 끝났는지 확인하기 전에 옛 것을 치우면 안 된다는 뜻이다.
비호환 변경을 안전하게 만드는 방법
두 설정이 공존할 수 없는 변경이라면, 공존할 수 있는 단계로 쪼갠다.
[한 번에 바꾸기]
옛 설정 제거 + 새 설정 추가 동시 적용 ← 전환 중 한쪽이 비는 구간 발생
[두 단계로 쪼개기]
1) 새 설정 추가 (옛 설정 유지) → 전파 완료 확인
2) 옛 설정 제거 → 전파 완료 확인
이 패턴은 인프라 곳곳에서 같은 모양으로 나타난다. ElastiCache 접속 보안 구조의 AUTH Token 로테이션도 ROTATE로 새 토큰을 추가한 뒤 SET으로 옛 토큰을 제거하는 2단계였다. 다만 그쪽에서는 2단계를 끝내지 않아 한 달 뒤 장애가 났다. 쪼개는 순간 "끝내는 것"이 새로운 과제가 된다는 점도 같이 기억해야 한다.
적용 절차 (실제로 한 순서)
-
STG 환경에 먼저 적용
- CF Function 생성 후 publish
- STG CloudFront에 연결하고 Custom Error Response 제거
- 기존 portal 동작 정상 확인
-
PROD 환경에 적용
- 동일한 CF Function 생성 후 publish
- PROD CloudFront에 연결하고 Custom Error Response 제거
- 배포 전파 완료 후 portal 정상 확인
STG에서 검증한 뒤 PROD에 적용했고, PROD 적용 시에도 다운타임 없이 전환이 끝났다.
배포 상태와 실제 동작 확인
aws cloudfront get-distribution --id [distribution-id] --query "Distribution.Status"InProgress: 전파 중 (기존 설정으로 서빙되는 엣지 존재)Deployed: 전파 완료 (모든 엣지에 새 설정 적용)
상태값만으로는 부족할 때가 있다. 전파 중에 실제로 어떤 응답이 오는지 보려면 요청을 직접 보내보는 게 확실하다. 응답 헤더의 X-Cache와 X-Amz-Cf-Pop을 보면 어느 엣지에서 처리됐는지 알 수 있어서, 서로 다른 엣지가 같은 결과를 주는지 확인할 수 있다.
정리
- CloudFront 배포 업데이트는 엣지별로 점진적으로 전파되고, "설정 없음" 상태는 생기지 않는다
- 무중단이 보장하는 건 요청 처리 여부지, 어떤 설정으로 처리되는지가 아니다
- 안전한 전환의 조건은 속도가 아니라 옛 설정과 새 설정이 같은 결과를 내는가이다
- 공존할 수 없는 변경이라면 추가와 제거를 두 단계로 쪼갠다
- 상태값(
Deployed) 확인과 실제 응답 확인은 별개의 검증이다
배운 점
문서를 인용해 답하는 것과 확인하고 답하는 것은 다르다. "다운타임 없이 되나요"라는 질문에 전파 방식을 직접 확인하고 나니, 다음 변경부터 망설임이 줄었다. 한 번 확인해 둔 사실은 그 뒤의 모든 작업 속도를 바꾼다.
질문을 바꾸는 게 더 중요했다. 다운타임이 생기느냐가 아니라, 전환 기간에 두 설정이 공존해도 괜찮으냐가 진짜 질문이었다. 이 질문으로 바꾸고 나니 어떤 변경이 위험한지도 같이 보였다.
같은 구조가 다른 기술에서도 반복된다. 새것을 추가하고 옛것을 나중에 제거하는 2단계 전환은 CloudFront에도, 토큰 로테이션에도, DB 스키마 변경에도 똑같이 나타난다. 기술마다 이름이 다를 뿐 해결하려는 문제가 같다는 걸 알고 나면, 처음 보는 작업도 어디를 조심해야 할지 짐작할 수 있다.
이어 읽기
- CloudFront Function을 활용한 멀티 SPA 프론트엔드 CI/CD 구축기: 이 검증이 필요했던 실제 변경
- ElastiCache 접속 보안 구조: AUTH Token + TLS 이중 보안: 같은 2단계 전환 패턴
- 사내 통합 포털 운영 가이드: 변경 대상 서비스의 운영 구조