전환 시각에 설정을 바꾸지 않고, CloudFront Function이 요청 시각을 보고 카운트다운과 실서비스를 자동으로 고르게 만든 경험을 정리했습니다.
1. 들어가며
서비스를 공개할 때 하나의 주소에서 시간에 따라 다른 화면을 보여줘야 하는 경우가 있습니다. 이벤트 전에는 안내 페이지를, 오픈이 가까워지면 카운트다운을, 정해진 시각부터는 실제 서비스를 제공하는 식입니다.
문제는 전환 시각마다 운영자가 설정을 변경해야 한다면 작업 시간과 설정 전파를 고려해야 한다는 점입니다. 사용자가 어느 경로로 접속하든 같은 단계의 화면을 보게 할지, 이미 페이지를 열어 둔 사용자는 어떻게 전환할지도 정해야 합니다.
이번 사례에서도 운영 도메인에 카운트다운 페이지를 노출하다가 정해진 시각에 실제 서비스로 전환해야 했습니다. 개발사에서는 SPA 구조상 React 소스를 수정하기 어려워, 애플리케이션 밖에서 자동으로 전환할 방법을 문의했습니다.
화면은 시간에 따라 세 단계로 바뀌어야 했습니다.
| 시각 (KST) | 화면 |
|---|---|
| 7/6 20:18 | 사전 안내 페이지 |
| 7/7 20:18 | 24시간 카운트다운 |
| 7/8 20:18 | 실제 서비스 오픈 |
처음 떠오른 방법은 카운트다운용 임시 EC2를 띄우고, 전환 시각에 ALB Target Group이나 CloudFront Origin을 사람이 바꾸는 것이었습니다.
하지만 오픈 당일 전환 시각에 콘솔을 붙잡고 설정을 바꾸는 건 불안합니다. 반영이 늦을 수도 있고, 급한 마음에 엉뚱한 Target Group을 고를 수도 있죠.
그래서 발상을 바꿨습니다. 전환 시각에 설정을 바꾸지 말고, 미리 배포해 둔 코드가 요청이 들어온 시각을 보고 알아서 목적지를 고르게 하자.
2. 왜 CloudFront Functions인가
필요한 판단은 딱 세 가지였습니다.
- 운영 도메인으로 들어온 요청인가?
- 지금 몇 시인가?
- 카운트다운(S3)으로 보낼까, 실제 서비스(ALB)로 보낼까?
세 가지 모두 요청 정보와 현재 시각만 있으면 판단할 수 있고, 외부 API를 호출하거나 무거운 연산을 할 필요도 없었습니다. 그래서 Lambda@Edge 대신 더 가벼운 CloudFront Functions를 선택했습니다.
CloudFront Functions는 CloudFront Edge에서 캐시를 확인하기 전에 실행되는 경량 JavaScript입니다. 이번처럼 짧은 분기 처리에 잘 맞고, 비용은 CloudFront 요금제에 따라 다릅니다. 종량제에서는 월 200만 회까지 무료이고 초과 호출에 요금이 발생하지만, 정액 요금제에서는 CloudFront Functions 실행이 플랜에 포함됩니다.
3. 전체 구성
전체 요청 흐름은 아래와 같습니다.

카운트다운 페이지는 정적 파일로 만들어 S3에 올렸고, CloudFront에는 경로(Behavior)를 두 개 두었습니다.
- Default Behavior → ALB (실제 서비스)
- /countdown/* Behavior → S3 (사전 안내·카운트다운 페이지)
그리고 두 Behavior의 Viewer Request에 같은 Function을 연결했습니다. 오픈 전에는 Function이 /countdown/…으로 302 Redirect를 돌려주고, 오픈 후에는 요청을 그대로 통과시켜 ALB로 보냅니다.
덤으로 오픈 전 운영 도메인에서 안내 페이지로 향하는 요청은 CloudFront와 S3가 처리했습니다. 다만 별도로 허용한 테스트 도메인의 요청은 실제 서비스로 전달될 수 있습니다.
4. 코드 살펴보기
전체 코드는 짧지만, 중요한 부분만 끊어서 보겠습니다. (도메인과 경로는 예시로 바꿨습니다.)
4.1 전환 시각 설정
// 2026-07-08 20:18 KST = 11:18 UTC (월은 0부터: 6 = 7월)
var OPEN_AT = Date.UTC(2026, 6, 8, 11, 18, 0);
var COUNTDOWN_START_AT = Date.UTC(2026, 6, 7, 11, 18, 0);
여기서 실수하기 쉬운 게 두 가지입니다.
- KST는 UTC+9라서 9시간을 빼야 합니다.
- JavaScript의 월은 0부터 시작해서 6이 7월입니다.
배포 전에 꼭 교차 확인하세요. 참고로 Function 안의 Date.now()는 사용자 PC가 아니라 Edge 서버의 시각입니다. 사용자가 단말 시간을 바꿔도 소용없습니다.
4.2 Redirect 응답
function redirect(location) {
return {
statusCode: 302,
statusDescription: 'Found',
headers: {
location: { value: location },
'cache-control': { value: 'no-store, no-cache, must-revalidate' }
}
};
}
no-store가 핵심입니다. 브라우저가 “카운트다운으로 가라”는 302를 기억해 버리면, 오픈 후에도 계속 카운트다운으로 튕길 수 있습니다.
그런데 왜 URI를 바꾸지 않고 굳이 Redirect를 할까요? Function에서 URI를 바꿔도 이미 선택된 Behavior와 Origin은 그대로이기 때문입니다.
Default Behavior로 들어온 요청은 URI만 /countdown/index.html로 바뀐 채 ALB로 가 버립니다. 브라우저가 새 경로로 다시 요청하게 해야 CloudFront가 /countdown/* Behavior를 골라 S3로 보냅니다.
4.3 도메인 분기
var host = request.headers.host ? request.headers.host.value : '';
if (host !== PROD_HOST) {
return request; // 테스트·API·Admin 도메인은 그대로 통과
}
같은 Distribution에 테스트 도메인도 붙여 두었기 때문에, Host로 걸러 운영 도메인에만 시간 분기를 적용했습니다.
덕분에 일반 사용자에게 카운트다운을 보여주는 동안에도 개발사는 테스트 도메인으로 실제 서비스를 미리 점검할 수 있었습니다.
4.4 오픈 이후 처리
if (now >= OPEN_AT) {
if (uri === PREVIEW_PATH || uri === COUNTDOWN_PATH ||
uri === '/countdown' || uri === '/countdown/') {
return redirect('/');
}
return request; // → Default Behavior → ALB
}
오픈 뒤에 즐겨찾기해 둔 카운트다운 URL로 들어오는 사람도 있습니다. 이런 요청은 /로 돌려보냅니다.
단, 이 분기가 동작하려면 Function이 /countdown/* Behavior에도 연결돼 있어야 합니다. Default에만 연결하면 이 요청은 Function을 거치지 않고 S3로 직행합니다.
4.5 정적 리소스 예외
if (uri.indexOf('/countdown/landingStatic/') === 0) {
return request;
}
이 예외가 없으면 화면이 깨집니다. HTML은 열리는데 CSS, JS, 이미지 요청까지 카운트다운 HTML로 Redirect되기 때문입니다. 테스트 때 한 번 겪으면 바로 이해되는 부분입니다.
4.6 단계별 분기
if (now < COUNTDOWN_START_AT) {
return uri === PREVIEW_PATH ? request : redirect(PREVIEW_PATH);
}
return uri === COUNTDOWN_PATH ? request : redirect(COUNTDOWN_PATH);
각 구간에서는 해당 단계의 HTML만 통과시키고, 나머지 경로는 전부 그 페이지로 보냅니다. 운영 도메인 어디로 들어와도 현재 단계의 화면을 보게 됩니다.
4.7 열려 있는 페이지 처리
CloudFront Function은 요청이 들어올 때만 실행됩니다. 따라서 사용자가 카운트다운 페이지를 계속 열어 두면 전환 시각이 지나도 화면은 바뀌지 않습니다. 이 부분은 카운트다운 페이지에 자동 새로고침 코드를 추가해 처리했습니다. 전환 시각에 페이지가 새로고침되면, 그때 들어온 요청을 Function이 실제 서비스로 보냅니다.
5. 주의할 점
- 전환 시각에 배포하지 마세요. LIVE로 게시하면 전파에 시간이 걸립니다. 코드와 연결은 미리 끝내 두고, 전환 시각에는 코드 안의 시간 조건만 바뀌게 해야 합니다.
- 테스트는 시각을 당겨서 하세요. DEVELOPMENT 단계에서 전환 시각을 몇 분 뒤로 바꿔 세 구간을 다 확인하고, 실제 시각으로 되돌린 뒤 게시했습니다. 시크릿 모드와 모바일에서도 꼭 확인하세요.
- 테스트 도메인은 정리하세요. Basic Auth를 넣었다면 오픈 후 인증 로직과 DNS 레코드를 정리합니다.
6. 마치며
결과적으로 새로 들어온 요청은 사전 안내 → 카운트다운 → 실제 서비스 순서로 일정대로 전환됐고, 오픈 당일 전환 시각에 아무도 콘솔을 만지지 않았습니다.
돌아보면 핵심은 CloudFront Functions라는 도구보다 “전환 시각에는 아무것도 바꾸지 않는다”는 원칙이었습니다.
덕분에 오픈 시각에는 별도의 설정 변경 없이 새 요청을 예정된 화면으로 보낼 수 있었습니다. 정해진 시간에 화면을 바꿔야 하는 서비스라면 참고할 만한 방식입니다.