문서화와 인수인계 시리즈 4/9
아키텍처 결정 기록, 흔히 ADR이라고 부르는 문서는 거창해 보인다. 대규모 조직이나 플랫폼 팀에서나 쓰는 문서처럼 느껴질 수도 있다.
하지만 작은 운영 도구를 만들 때도 ADR은 필요하다.
이유는 단순하다. 시간이 지나면 왜 그렇게 만들었는지 잊어버리기 때문이다.
코드는 최종 결과만 보여준다. 하지만 그 결과에 도달하기까지의 선택지, 제약, 포기한 것, 다시 검토해야 할 조건은 코드에 남지 않는다.
문제 상황
운영 콘솔을 만들면서 여러 결정을 내려야 했다.
- React SPA를 어디에 배포할 것인가
- API 앞에 Gateway를 둘 것인가
- Lambda만 쓸 것인가, 상주 서버도 둘 것인가
- RDB를 둘 것인가, 파일 기반 저장소로 충분한가
- 오래 걸리는 엑셀 생성은 동기 API로 처리할 것인가
- CORS preflight는 어디서 처리할 것인가
이 결정들은 단순 취향이 아니었다. 사용자의 수, 데이터의 성격, 운영 인력, 비용, 장애 영향 범위, 배포 편의성을 고려한 결과였다.
그런데 문서로 남기지 않으면 나중에는 이렇게만 기억된다.
그냥 Lambda 썼던 것 같은데?
그냥 S3에 올렸던 것 같은데?
그냥 API Gateway 붙였던 것 같은데?
이렇게 되면 구조를 바꿔야 할 때 다시 처음부터 고민해야 한다.
ADR이 남겨야 하는 것
ADR은 기술 목록이 아니다.
좋은 ADR은 다음을 남긴다.
- 당시의 문제 상황
- 고려한 선택지
- 최종 결정
- 선택한 이유
- 선택하지 않은 이유
- 얻은 것
- 포기한 것
- 다시 검토할 조건
이 중에서 가장 중요한 것은 선택하지 않은 이유다.
예를 들어 S3 + CloudFront를 사용했다는 사실보다 중요한 것은 다음 질문에 대한 답이다.
- 왜 EC2 + Nginx가 아니었는가
- 왜 외부 호스팅 서비스를 쓰지 않았는가
- 왜 S3 단독 정적 호스팅으로 충분하지 않았는가
선택하지 않은 대안이 있어야 결정의 무게가 생긴다.
ADR 기본 템플릿
복잡한 형식이 필요하지는 않다.
다음 정도면 충분하다.
## 결정 제목
### 배경
어떤 문제가 있었는가.
### 고려한 선택지
1. 선택지 A
2. 선택지 B
3. 선택지 C
### 결정
무엇을 선택했는가.
### 선택한 이유
왜 이 선택이 당시 조건에서 합리적이었는가.
### 포기한 것
이 결정으로 어떤 비용이나 한계를 받아들였는가.
### 다시 검토할 조건
어떤 상황이 되면 이 결정을 바꿔야 하는가.
형식보다 중요한 것은 판단 근거다. 문서가 예쁘지 않아도, 나중에 다시 읽었을 때 당시의 생각이 복원되면 된다.
예시 1. API Gateway를 둔 결정
API Gateway를 Lambda 앞에 둔 결정은 좋은 ADR 주제다.
단순히 "API Gateway를 사용했다"고 쓰면 별 의미가 없다.
다음처럼 써야 한다.
브라우저 기반 SPA가 별도 도메인의 API를 호출해야 했고, 대부분 JSON 요청이어서 preflight가 발생했다. Lambda Function URL만으로도 HTTP 엔드포인트를 만들 수 있었지만, path별 라우팅, OPTIONS MOCK 응답, Access Log, 스로틀링, 추후 백엔드 교체 가능성을 고려해 API Gateway를 앞단에 두었다.
이렇게 남기면 나중에 누군가 "Function URL로 바꾸면 안 되나요?"라고 물었을 때 답할 수 있다.
바꿀 수 있다. 하지만 그때는 CORS, 로깅, 스로틀링, 라우팅, 백엔드 교체 가능성을 다시 비교해야 한다.
ADR은 결정을 고정하는 문서가 아니라, 다시 판단할 기준을 남기는 문서다.
예시 2. RDB를 쓰지 않은 결정
어떤 콘솔에서는 RDB를 쓰지 않고 S3 JSON 파일만으로 데이터를 제공할 수 있었다.
이 결정도 그냥 "DB 없음"이라고 쓰면 위험하다. 누군가는 비용을 아끼려고 대충 만든 것으로 오해할 수 있다.
ADR에는 조건을 적어야 한다.
데이터 원천은 이미 외부 스프레드시트에 있고, 애플리케이션은 그 데이터를 조회하기 쉬운 형태로 캐싱해 제공한다. 데이터 규모는 작고, 쓰기 경합이 거의 없으며, 공개용 데이터는 별도 JSON으로 가공할 수 있다. 따라서 별도 RDB를 운영하는 비용과 책임보다 S3 JSON 스냅샷 구조가 더 단순하다.
이렇게 쓰면 "언제 DB가 필요해지는가"도 자연스럽게 정리된다.
- 데이터 규모가 커질 때
- 동시 쓰기가 많아질 때
- 복잡한 검색 조건이 필요할 때
- 강한 일관성이 필요할 때
- 권한 모델이 복잡해질 때
좋은 ADR은 선택의 유효 범위를 함께 남긴다.
예시 3. Lambda와 상주 서버를 함께 쓴 결정
서버리스와 상주 서버는 종종 선택지처럼 이야기된다.
하지만 실무에서는 둘을 섞는 것이 더 자연스러울 때가 있다.
ADR에는 이렇게 적을 수 있다.
대시보드 조회처럼 짧고 잦은 요청은 DB connection pool과 낮은 지연이 중요하므로 상주 API 서버로 처리한다. 반면 리포트 생성처럼 드물고 오래 걸리는 작업은 Lambda worker로 분리한다. 이렇게 하면 일반 조회 트래픽과 무거운 파일 생성 작업의 장애 영향 범위를 나눌 수 있다.
이 문장은 나중에 구조를 설명할 때 그대로 쓸 수 있다.
면접에서도 도움이 된다. 하지만 면접 답변을 만들기 위해 쓴 문서가 아니다. 운영 판단을 기록했기 때문에 면접 답변으로도 쓸 수 있는 것이다.
ADR은 변경을 막지 않는다
ADR을 쓰면 결정이 굳어지는 것처럼 느껴질 수 있다. 하지만 실제로는 반대다.
좋은 ADR은 변경을 쉽게 한다.
왜냐하면 변경 전 확인해야 할 조건이 문서에 남아 있기 때문이다.
예를 들어 다음처럼 쓸 수 있다.
다음 조건이 되면 ECS Fargate 이전을 검토한다.
- 상주 API 서버가 여러 개 필요해진다.
- 무중단 배포가 중요해진다.
- 배포 빈도가 늘어나 단일 EC2 운영이 부담된다.
- 컨테이너별 스케일링이 필요해진다.
이렇게 적어두면 나중에 "지금 ECS로 가야 하나?"라는 질문이 나왔을 때 감으로 결정하지 않아도 된다.
ADR과 블로그 글의 차이
ADR은 내부 문서다. 실제 리소스명, 내부 도메인, 구체적인 장애 맥락이 들어갈 수 있다.
블로그 글은 다르다. 공개 글에서는 식별 정보를 제거하고 판단 구조만 남겨야 한다.
ADR:
실제 API Gateway ID, 실제 Lambda 함수명, 실제 도메인, 실제 DB명 포함 가능
블로그:
API Gateway, Lambda worker, 운영 DB, console.example.com처럼 일반화
내부 ADR을 그대로 공개하면 안 된다. 하지만 ADR은 블로그 글의 좋은 원천이 된다. 이미 선택지와 판단 이유가 정리되어 있기 때문이다.
작은 프로젝트에도 ADR이 필요한 이유
작은 프로젝트에서는 문서화가 과하다고 느낄 수 있다.
하지만 작은 프로젝트일수록 한 사람이 많은 결정을 빠르게 내린다. 그 결정이 머릿속에만 있으면 시간이 지나 사라진다.
ADR은 거창한 회의록이 아니다.
한 결정에 대해 10분만 써도 충분하다.
- 왜 이걸 선택했는가
- 무엇을 선택하지 않았는가
- 어떤 상황이 되면 바꿀 것인가
이 세 가지만 남겨도 나중에 큰 차이가 난다.
정리
ADR은 면접 답변을 만들기 위한 문서가 아니다.
하지만 좋은 ADR은 나중에 면접 답변이 된다. 실무에서 실제로 고민한 문제, 비교한 선택지, 받아들인 트레이드오프가 들어 있기 때문이다.
무엇을 썼는지보다 중요한 것은 왜 그렇게 했는지다.
코드는 현재의 답을 보여준다. ADR은 그 답에 도달한 이유를 남긴다.
운영 시스템에서 그 이유는 자산이다.
'일 > 시스템 설계' 카테고리의 다른 글
| README, 아키텍처 문서, HANDOVER는 역할이 다르다 (0) | 2026.05.24 |
|---|---|
| HANDOVER.md에 꼭 들어가야 하는 항목들 (0) | 2026.05.23 |
| 인수인계 문서는 코드 설명서가 아니라 운영 지도다 (0) | 2026.05.22 |
글에서 정리한 생각은 GitHub의 코드와 포트폴리오로 이어지고, 일부는 FamBlend 같은 제품 실험으로 확장됩니다.