문서화와 인수인계 시리즈 7/9
배포 가이드를 쓰다 보면 명령어만 나열하기 쉽다.
npm run build
aws s3 sync build/ ...
aws cloudfront create-invalidation ...
물론 명령어는 필요하다. 하지만 배포 가이드가 명령어 모음으로 끝나면 위험하다.
좋은 배포 가이드는 "무엇을 실행할지"뿐 아니라 "언제 실행하고, 무엇을 조심하고, 어떻게 확인하고, 실패하면 어떻게 되돌릴지"를 설명해야 한다.
문제 상황
운영 콘솔 배포에는 여러 종류가 있었다.
- React SPA 빌드 후 S3 업로드
- CloudFront 캐시 무효화
- Lambda 함수 코드 업데이트
- Lambda Layer 유지
- EC2의 Node API 서버 배포
- Google Apps Script 배포
- API Gateway stage 배포
각 배포는 명령어가 다르고, 실패했을 때 영향도 다르다.
특히 정적 파일과 데이터 파일이 같은 저장소 안에 있을 때는 더 조심해야 한다. 잘못된 sync 명령어 하나로 운영 데이터 경로를 덮어쓸 수 있다.
그래서 배포 가이드는 절차 문서이면서 동시에 안전장치여야 한다.
배포 가이드에 들어가야 할 것
배포 가이드는 다음 구조가 좋다.
- 배포 대상
- 사전 확인
- 실행 명령어
- 배포 후 검증
- 롤백 또는 복구 방법
- 주의사항
이 순서를 지키면 명령어 중심이 아니라 운영 흐름 중심의 문서가 된다.
1. 배포 대상
먼저 무엇을 배포하는지 분명히 해야 한다.
예를 들어 같은 콘솔이라도 배포 대상은 여러 개일 수 있다.
| 대상 | 설명 |
|---|---|
| Frontend SPA | React build 산출물 |
| Lambda API | 서버리스 API 함수 |
| Node API | 상주 Express 서버 |
| Static public page | 외부 사용자용 HTML |
| Automation script | 외부 스크립트 |
배포 대상이 다르면 확인할 것도 다르다.
프론트엔드만 바꿨는데 Lambda를 배포할 필요는 없다. API만 바꿨는데 CloudFront 캐시 문제로 착각할 수도 있다.
2. 사전 확인
배포 전에 확인할 목록이 있어야 한다.
예시:
- 현재 브랜치가 맞는가
- 환경 변수가 맞는가
- 빌드가 성공하는가
- 배포 대상 환경이 production인지 staging인지 확인했는가
- 데이터 파일을 덮어쓰지 않는 exclude 옵션이 있는가
- Lambda Layer를 유지하는가
- 배포 후 확인할 URL이 준비되어 있는가
사전 확인은 귀찮아 보이지만, 배포 사고 대부분은 실행 전 확인 부족에서 나온다.
3. 실행 명령어
명령어는 정확해야 한다.
하지만 실제 내부 문서와 공개 글은 달라야 한다.
내부 문서:
npm run build
aws s3 sync build/ s3://실제-버킷명/build/ --delete --exclude "data/*"
aws cloudfront create-invalidation --distribution-id 실제배포ID --paths "/*"
공개 글:
npm run build
aws s3 sync build/ s3://static-assets-bucket/build/ --delete --exclude "data/*"
aws cloudfront create-invalidation --distribution-id DISTRIBUTION_ID --paths "/*"
내부 문서에는 실제 값이 필요하다. 공개 글에는 패턴만 남긴다.
4. 배포 후 검증
배포가 끝났다는 것은 명령어가 성공했다는 뜻이 아니다.
사용자가 보는 화면과 API가 정상이어야 배포가 끝난 것이다.
프론트엔드 배포 후 확인할 것:
- 메인 페이지가 열리는가
- SPA 라우팅이 새로고침 후에도 동작하는가
- 정적 자산이 404 없이 로드되는가
- API 호출이 정상인가
- 브라우저 Console 오류가 없는가
Lambda 배포 후 확인할 것:
- health check 또는 대표 API가 정상 응답하는가
- CloudWatch Logs에 import 오류가 없는가
- 환경 변수가 누락되지 않았는가
- 의존성 Layer가 연결되어 있는가
EC2 서버 배포 후 확인할 것:
- container가 실행 중인가
- health check가 성공하는가
- DB 연결이 정상인가
- 로그에 인증 또는 CORS 오류가 없는가
검증 항목이 없으면 배포는 감으로 끝난다.
5. 롤백 또는 복구 방법
배포 가이드에는 롤백 방법이 있어야 한다.
완벽한 자동 롤백이 아니어도 된다. 최소한 어떻게 되돌릴 수 있는지 적어야 한다.
예시:
- 이전 build 산출물을 다시 S3에 업로드한다.
- 이전 Lambda zip을 다시 update-function-code 한다.
- 이전 Docker image tag로 container를 재시작한다.
- API Gateway stage를 이전 deployment로 되돌린다.
- 문제가 캐시라면 invalidation을 수행한다.
롤백 방법이 없으면 배포자는 실패를 두려워하게 된다. 실패했을 때의 경로가 있어야 배포도 안정된다.
6. 주의사항
주의사항은 배포 가이드에서 가장 중요할 수 있다.
예를 들어 다음과 같은 항목이다.
- S3 sync 시 데이터 경로를 덮어쓰지 않는다.
- Lambda Layer를 제거하지 않는다.
- CloudFront invalidation 없이 화면 반영이 늦을 수 있다.
- API Gateway 설정 변경 후 stage 배포를 잊지 않는다.
- production 환경 변수와 staging 환경 변수를 혼동하지 않는다.
- 외부 스크립트 배포 후 trigger가 유지되는지 확인한다.
주의사항은 단순한 금지 목록이 아니라 사고를 막는 경험의 축적이다.
데이터 파일을 덮어쓰지 않는 배포
정적 파일과 데이터 파일을 같은 bucket에서 관리하는 경우가 있다.
이때 배포 명령어는 특히 조심해야 한다.
aws s3 sync build/ s3://console-bucket/ --delete
이 명령어는 편하지만 위험할 수 있다. build 폴더에 없는 운영 데이터가 삭제될 수 있기 때문이다.
따라서 데이터 경로를 분리하거나 exclude 옵션을 명확히 둔다.
aws s3 sync build/ s3://console-bucket/ --delete \
--exclude "data/*" \
--exclude "latest/*"
이런 옵션은 왜 필요한지 문서에 적어야 한다. 그렇지 않으면 누군가 "불필요해 보인다"며 제거할 수 있다.
Lambda 배포에서 의존성 분리하기
Lambda 함수 배포도 명령어만 보면 단순하다.
zip function.zip lambda_function.py
aws lambda update-function-code --function-name api-function --zip-file fileb://function.zip
하지만 의존성을 Layer로 분리한 경우에는 주의할 점이 있다.
- 함수 zip에는 코드만 포함한다.
- 무거운 라이브러리는 Layer에 둔다.
- Layer를 교체하면 런타임 동작이 바뀔 수 있다.
- 코드 배포와 의존성 배포를 구분한다.
이 내용을 모르면 누군가 전체 site-packages를 zip에 넣어 배포 파일을 키우거나, 필요한 Layer를 제거할 수 있다.
배포 가이드를 블로그로 바꾸는 법
배포 가이드는 내부 명령어가 많기 때문에 그대로 공개하기 어렵다.
대신 다음 주제로 바꾸면 좋다.
- React SPA 배포에서 캐시 무효화를 빼먹으면 생기는 일
- S3 sync에서
--delete를 쓸 때 조심해야 할 것 - Lambda Layer로 배포 단위를 나누는 이유
- 배포 후 검증 체크리스트 만들기
- 작은 프로젝트에도 롤백 절차가 필요한 이유
실제 리소스명은 제거하고, 실무 원칙을 남긴다.
정리
배포 가이드는 명령어 모음이 아니다.
좋은 배포 가이드는 다음 질문에 답한다.
- 무엇을 배포하는가
- 배포 전에 무엇을 확인하는가
- 어떤 명령어를 실행하는가
- 배포 후 무엇으로 성공을 확인하는가
- 실패하면 어떻게 되돌리는가
- 어떤 실수를 가장 조심해야 하는가
명령어는 시간이 지나 바뀔 수 있다. 하지만 배포의 판단 순서와 주의사항은 오래 남는다.
그 순서를 문서화하는 것이 배포 가이드의 진짜 역할이다.
'성장과 기술 > 시스템 설계' 카테고리의 다른 글
| 트러블슈팅 문서는 장애가 난 뒤 쓰면 늦다 (0) | 2026.05.27 |
|---|---|
| 기술 용어집을 프로젝트 맥락으로 쓰는 이유 (0) | 2026.05.26 |
| ADR은 면접 답변이 아니라 운영 자산이다 (0) | 2026.05.25 |
| README, 아키텍처 문서, HANDOVER는 역할이 다르다 (0) | 2026.05.24 |
| HANDOVER.md에 꼭 들어가야 하는 항목들 (0) | 2026.05.23 |
글에서 정리한 생각은 GitHub의 코드와 포트폴리오로 이어지고, 일부는 FamBlend 같은 제품 실험으로 확장됩니다.