토스 러너스하이를 마치며 – 한 달 동안, 어디까지 해볼 수 있을까
토스 러너스하이를 마치게 되었다.
돌이켜보면, 가장 먼저 들었던 생각은 “나는 정말 운이 좋았다”였다.
이 프로그램이 나에게 던진 질문은 굉장히 단순했다고 생각한다.
“한 달이라는 시간을 줄 테니, 어디까지 해볼 수 있습니까?”
문제를 찾고 해결하는 사람이 되고 싶었다
(이전 글에 이어서 - 테스트 코드 기반 Swagger 문서를 생성)
나는 항상 “코드를 잘 짜는 개발자”보다
“부족한 부분을 찾아서 더 이롭게 만드는 개발자”가 되고 싶었다.
그리고 현업에서 일하면서 느낀 건 내가 개발자로서 가장 재미를 느끼는 순간은
- 새로운 기술을 쓰는 순간보다
- 성능을 튜닝하는 순간보다
“문제를 진단하고, 구조를 바꾸는 순간”이었다.
그게 ‘아, 나 지금 개발하고 있구나’라는 감각을 가장 강하게 느끼게 해줬다.
마침, 러너스하이가 시작되었다
문제를 진단하고 있던 바로 그 시점에 러너스하이에 참가하게 되었다.
그리고 이 프로그램이 나에게 준 가장 큰 제약은 딱 하나였다.
“한 달”이라는 시간적 제한.
한 달 안에서, 내가 진단한 문제를 어디까지 밀어붙일 수 있을까가 궁금해졌다.
그래서 나는 스스로에게 이렇게 제안했다.
“좋아, 한 달 동안 내가 진짜 풀고 싶은 문제를 정해서 끝까지 달려보자.”
선정한 주제
프로세스 개선을 통해 배포 이후 커뮤니케이션 비용을 0으로 만들자.
이 주제를 선택한 이유는 단순했다. 이전에 SI 프로젝트를 진행하면서 몇 시간 단위로 바뀌는 기획과 요구사항 때문에
이미 만든 코드를 갈아엎고, 다시 만들고, 또 변경되고
이런 경험을 너무 많이 했다. 그래서 자연스럽게 이런 생각이 들었다.
“기획과 요구사항이 자주 바뀌는 환경이라면,
그 변화에 쉽게 대응할 수 있는 구조를 만들 수는 없을까?”
확장성 있는 구조, 변경에 강한 개발 방식, 그리고 무엇보다 협업 비용이 낮은 구조.
이걸 한 번 제대로 고민해보고 싶었다.
그런데, 진짜 문제는 따로 있었다
조금 더 깊게 들여다보니 문제는 코드가 아니라 협업 방식에 있었다.
특히, 백엔드 – 프론트 – QA 협업 흐름이 가장 큰 병목이었다.
기존 협업 흐름
- 백엔드가 프론트에게 API Spec 공유
- “이번 요구사항 변경으로 A API 신규, B API 수정 완료했습니다.”
- 프론트는 Swagger 문서를 보고 연결
- 테스트 중 오류 발생
→ 프론트 판단: “이건 백엔드 문제 같은데요?” - 백엔드가 다시 확인
- 원인 파악
- B API 필드명 전달 누락
- C API 필드 누락
여기서 이런 반론이 가능하다.
"그럼 누락된 부분 다시 공유하면 되는 거 아닌가요?”
맞다. 이론적으로는 그렇다. 그런데 현실은 조금 다르다.
Swagger 신뢰도 문제
우리가 사용하는 Swagger는 Spring REST Docs 테스트 코드 기반이다.
즉, 실제 코드 변경, 테스트 코드 변경 이 두 가지가 항상 같이 맞아야 한다.
만약 코드만 고치고 테스트 코드 수정을 안한다면 협업하는 프론트와 AI 팀은 이전 버전 Swagger를 계속 보고 작업하게 된다.
이 순간부터 문제가 생긴다.
- Swagger 문서 신뢰도 하락
- 실제 코드와 문서 불일치
- “이 문서가 최신이 맞나?”라는 불신
- 버전이 2개처럼 보이기 시작
그리고 여러 명이 이런 실수를 반복하면, 팔로우업 자체가 거의 불가능해진다.
결국 백엔드는 테스트 코드 재 수정, 재 배포 여기서 끝이 아니다.
배포 과정의 또 다른 문제
배포는 Git push 이후 자동화되어 있다.
하지만, CI가 성공했는지 CD가 성공했는지 알 수 있는 방법이 없다.
그래서 개발자는 Drone 대시보드 보고 ArgoCD 대시보드 보면서 모니터링한다.
(문제 2: 배포 중 지속적인 집중력 분산)
게다가 배포 하나에 평균 7분 20초.
이 시간 동안 개발자는 다른 업무와 병행하면서 계속 배포만 바라본다.
결국 정리해보니, 문제는 이것이었다
우리가 진짜 원했던 건 이거였다.
- 변경된 코드에 맞게 테스트 코드와 스펙이 항상 같이 변경되고
- 변경된 API 스펙이 누락 없이 정확하게 공유되고
- 배포가 끝났을 때 프론트와 QA가 자동으로 인지하고 바로 시작할 수 있는 구조
그래야 재배포가 줄어들고 프론트 → 백엔드 문의 루프가 사라지고 QA 지연도 없어지고
“배포 이후 커뮤니케이션 비용” 자체가 사라질 수 있다.
그래서 떠올린 아이디어
그 순간 머릿속에 하나의 생각이 떠올랐다.
“배포가 끝났을 때,
이전 배포와 이번 배포의 API 스펙을 자동으로 비교해서
변경된 내용을 그대로 공유해주면 어떨까?”
만약 이전 OpenAPI 스펙과 현재 OpenAPI 스펙을 자동으로 비교하고
그 결과를 프론트, QA , 관련 담당자에게 자동으로 전달할 수 있다면?
그러면 누락도 없어지고, 설명도 필요 없고 , 재문의도 줄어들고 QA도 바로 시작할 수 있다.
이 아이디어 하나로 위에서 겪었던 거의 모든 문제가 한 번에 풀릴 수 있다고 생각했다.
그래서, 시작했다
이걸 실제로 만들 수 있을까?
- CI 단계에서 OpenAPI 스펙을 저장하고
- CD 단계에서 이전/현재를 비교하고
- 배포 이벤트를 기준으로 Bot이 자동으로 분석하고
- 결과를 팀에 자동으로 전달하는 구조
“배포 이벤트 기반 Bot 자동화 파이프라인”
한 달이라는 제한 안에서 이걸 끝까지 만들어보기로 했다. 그리고, 그게 이번 러너스하이 한 달의 경주였다.
0. 한 달의 목표
지난 한 달 동안의 목표는 명확했다.
개발 속도를 높이거나 인력을 충원하는 것이 아닌,
시스템과 자동화를 통해 팀의 한계를 보완하는 것
입사 후 약 6개월간 실무를 진행하면서 느낀 건, 개인의 개발 역량과 무관하게 업무 프로세스 자체가 속도와
품질을 제한하는 순간이 반복적으로 온다는 점이었다.
기능 구현이나 기술 선택이 아니라, 배포 이후의 흐름(공유/확인/QA)이 구조적으로 정리되지 않아 병목이 생기는 상황이 보였다.
이걸 한 문장으로 요약하면 이랬다.
“배포 이후의 상태 변화가 시스템이 아닌 사람에 의존하고 있었다.”
1. 문제를 어떻게 인식했는가
처음엔 각각 다른 문제처럼 보였다.
하지만 실제로는 배포 이후 흐름에서 같은 패턴이 반복되고 있었다.
문제 1) 배포 이후 API 변경사항 공유 누락
배포 이후 프론트팀에서 이런 질문이 자주 왔다.
- “이번에 이 API가 변경된 게 맞나요?”
- “응답 구조가 기획이랑 다른것 같아요”
그 질문에 답하기 위해 나는
원인을 다시 찾고, 커밋을 확인하고, 결과적으로 수정/재배포까지 하게 되는 경우가 있었다.
배포 이후 검증 비용이 크게 증가하고 있었다.

문제 2) CI/CD 배포 과정에서의 집중력 분산
배포 중에는 개발 흐름이 자주 끊겼다.
“빌드 끝났나?” “ArgoCD Sync 성공했나?”
Drone/ArgoCD 대시보드를 오가며 수동으로 확인해야 했고,
하나의 작업이 여러 번 끊기는 컨텍스트 체인지가 생겼다.

문제 3) QA 진행의 수동적 구조
배포가 끝나도 QA는 바로 시작되지 않았다.
- 엑셀로 개발 완료 여부를 관리하고
- 개발자가 엑셀 수정하거나 QA팀에 따로 공유하고
- 공유되지 않을경우, QA팀은 엑셀을 수시로 열어 확인했다.
그 결과 개발 완료 → QA 착수까지 수 시간~반나절 공백이 반복됐다.

2. 왜 이 문제가 중요하다고 판단했는가
처음엔 “불편하다” 수준으로 생각했다.
하지만 반복되면서 깨달았다.
이건 불편함이 아니라 팀의 품질과 속도를 동시에 갉아먹는 구조적 문제였다.
- API 변경 공유가 누락되면 → 프론트 재문의 → 백엔드 재확인 → 재배포로 이어진다.
- (즉, 배포 이후 비용이 기하급수적으로 증가한다.)
- CI/CD 결과 전달이 자동화되지 않으면 → 개발자는 배포 중에도 계속 확인해야 한다.
- (즉, 자동화된 배포가 집중력을 분산시키는 상황이 생긴다.)
- QA가 수동이면 → 개발 완료가 곧바로 검증으로 이어지지 않는다.
- (즉, 리드타임이 길어지고 피드백 루프가 느려진다.)
그리고 세 문제는 결국 같은 문제였다.
3. 접근 방식이 어떻게 바뀌었는가
처음에는 “공유를 더 잘하자”, “체크리스트를 만들자”처럼
사람의 노력을 늘리는 방식을 떠올렸다.
하지만 그건 근본 해결이 아니었다.
사람이 더 열심히 해야만 돌아가는 구조는 결국 다시 무너진다.
그래서 방향을 바꿨다.
“배포 이후의 모든 상태 변화를 Bot이 책임지는 시스템 이벤트로 만들자.”
4. 배포 이후 모든 것을 책임지는 Bot 구현 기록

문제 1) API 변경사항 공유 누락 → OpenAPI Diff 자동 리포트
처음 떠올린 해결방법
이미 CI maven test 단계에서 REST Docs 기반 OpenAPI문서를 생성하고 있었다.
(테스트 코드 기반 Swagger 문서를 생성 - 이전 이야기)
그렇다면,
- 이전 배포 스펙 vs 현재 배포 스펙을 비교해서
- 변경 사항(diff.json)을 추출하고
- 자동으로 업무 채널로 전송되면
“이번 배포에서 뭐가 바뀌었는지”를 사람이 설명하지 않아도 된다.
부딪힌 한계
하지만 CI는 clean 빌드 기반이라 Stateless 했다.
즉, 이전 스펙을 보관할 방법이 없었다.
그래서 CI의 역할을 재정의했다.
CI는 “생성”만 담당하고, 스펙의 보관은 외부 컴포넌트가 담당한다.
해결: OpenAPI Uploader Pod + PV(PVC)로 Stateful 보관
OpenAPI 스펙을 전담 관리하는 Uploader Pod를 따로 두고,
PV에 바인딩된 PVC를 마운트해 /data/current, /data/previous 형태로 관리했다.

CI 흐름은 이렇게 바뀌었다.
- CI에서 openapi-3.0.json 생성
- 생성된 스펙을 Uploader Pod로 전달
- Uploader Pod가 PV 경로에 저장
- meta.txt(브랜치/작성자/커밋/Jira)도 함께 저장
스펙을 보관한 뒤, 다음 문제가 남아 있었다
이제는 Uploader Pod에
이전/현재 OpenAPI 스펙을 안정적으로 보관할 수 있게 됐다.
하지만 여기서 끝이 아니었다.
“이 스펙을 언제, 어디서, 누가 비교하고
그 결과를 책임져야 할까?”
스펙 비교와 변경 분석은 CI 단계에서는 이미 늦었고,
단순한 알림 설정으로 해결될 문제도 아니었다.
CD 단계에서 “분석 책임” 분리 → Job 도입
초기에는 ArgoCD Notification ConfigMap도 검토했다.
하지만 바로 한계가 보였다.
- ConfigMap은 배포 결과를 ‘알리는 역할’은 가능하지만분석 책임을 맡기엔 구조적으로 맞지 않았다.
- diff 생성 / 변경 분류 / 메시지 가공 같은
- 설정 파일에 실행 로직과 판단 로직이 섞이면
- 유지보수 비용이 급격히 커질 수 있었다.
그래서 방향을 명확히 정했다.
“알림이 아니라,
변경 분석 자체를 책임지는 실행 단위가 필요하다.”
그 역할을 Job이 맡도록 했다.
실행 타이밍: 왜 PostSync인가
변경 분석과 알림은 반드시
- 배포가 성공적으로 완료된 이후
- 이전/현재 스펙이 확정된 이후
- 롤백 가능성이 남아있는 구간에서는 ‘절대 발송하면 안 된다’
라는 조건을 만족해야 했다.
그래서 PostSync를 선택했다.

PostSync Job 처리 흐름
PostSync Job은 PVC를 마운트해
- /data/previous/openapi.json
- /data/current/openapi.json
을 읽고 openapi-diff(2.1.6)로 비교했다.
- diff.json / diff.html 생성

- 변경 내용을 추가/수정/삭제/Deprecated로 분류

- 요청/응답 DTO 필드 단위로 가공
- Teams/Slack 웹훅으로 자동 전송

“자동화는 운영을 멈추게 해선 안 된다” → 영향도 검증
Job을 배포 파이프라인에 추가하는 것은
사내 Kubernetes 환경에서 처음 시도였다.
따라서 단순히 “동작한다”가 아니라,
운영 흐름에 부담을 주지 않는지를 반드시 확인해야 했다.
특히 아래 세 가지가 가장 중요했다.
- 배포 전체 흐름에 유의미한 지연을 만들지 않는지
- 클러스터 리소스를 과도하게 점유하지는 않는지
- 기존 애플리케이션 Pod나 다른 배포에 영향을 주지는 않는지
이를 판단하기 위해
이론적인 추정이 아니라 실제 운영 로그를 기준으로 관측했다.
- Job Pod: Pending → Running → Completed 약 5초
- 컨테이너 실행 구간: 약 3초 내외
이 수치를 통해
배포 안정성을 해치지 않으면서도 운영에 안전하게 적용 가능한 수준이라는 결론을 얻었다.

Bot 도입 이후 발생한 문제: Hook 중복 실행 → 멱등성으로 해결
PostSync Hook은 “네임스페이스 리소스 단위”로 반응했다.
즉, 한 번 배포에도 여러 리소스 Sync나 수동 Sync로 Job이 반복 실행될 수 있었다.
처음엔 “실행 자체를 막자”를 고민했다.
하지만 ArgoCD의 특성상 외부에서 완전히 통제하기 어려웠다.
그래서 관점을 바꿨다.
“실행을 제어하지 말고, 결과를 한 번만 발생시키자.” → 멱등성 보장
Job이 시작되면 meta.txt를 읽고 revision 기준으로 발송 이력을 확인했다.
- 이력 없음 → 알림 전송 + ${revision}:true 기록
- 이력 있음 → 스킵
그 결과, Sync가 여러 번 발생해도 알림은 한 번만 전송되도록 만들었다.
5. 확장 적용: 나머지 두 문제도 “이벤트”로 바꾸기
문제 2) CI/CD 결과 수동 확인 → 자동 알림으로 전환
배포 상태도 API 변경과 동일했다.
“사람이 확인해야 하는 정보가 아니라, 자동으로 전달되어야 하는 이벤트”
그래서
- CI(Drone) 빌드 성공/실패 알림
- CD(ArgoCD) Sync 성공/실패 알림
을 기존 업무 채널로 배포 정보와 함께 전달하도록 했다.

문제 3) QA 수동 구조 → 배포 완료 이벤트를 QA 트리거로
QA 역시 “엑셀 확인”이 아니라 “배포 완료 이벤트”로 전환했다.
- PostSync를 QA 시작 트리거로 활용
- QA팀을 알림 채널에 포함
- 알림 메시지에 QA에 필요한 정보 포함
- 기능(메뉴)
- Jira 티켓
- 작업자
- 브랜치/커밋
- 배포 시점
즉, 메시지 자체가 QA 요청서 역할을 하도록 만들었다.

결과
배포 이후 변경된 스펙을 자동 분석하여 API 추가·변경·삭제 내역을 공유하는 Bot


달라진점
- 배포 이후 “변경 공유 누락”으로 인한 재문의/재확인이 눈에 띄게 감소
- 배포 중 대시보드 수동 확인이 줄어들며 컨텍스트 스위칭 감소
- QA 착수까지의 대기 시간이 줄고, QA 요청이 명확해짐


실제 성과가 있었을까?
배포 이후 플로우 자체가 바뀌면서, 변화는 생각보다 빠르게 드러났다.
- 배포가 끝나면 변경 내용이 자동으로 공유되고
- 프론트 / QA가 바로 확인하고
- 추가 문의 없이 바로 작업을 이어가는 구조가 되었다
이 흐름이 반복되면서, 누구나 변화를 체감할 수밖에 없는 구조가 되었다.
특히 인상 깊었던 점은, 이 흐름이 개인 차원의 시도가 아니라
팀 단위의 프로세스로 자연스럽게 확장되었다는 점이다.
팀장님께서 직접 팀 회의 안건으로 올려주시고, 배포 프로세스 개선 사례로 공유해주시면서
“이 구조를 다른 서비스에도 적용해보자”는 이야기가 나오기 시작했다.

협업하는 프론트엔드 / QA 팀에서도 반응은 바로 나타났다.
- 배포 이후 재문의 감소
- 변경 사항 확인 시간 단축
- QA 착수 지연 거의 제거
무엇보다,
“이번 배포에서 뭐가 바뀌었는지 바로 알겠다”
“이제 따로 물어볼 일이 거의 없다”
라는 피드백이 나왔다는 점이 가장 의미 있었다.

회고: 어떻게 성장했는가
이번 한 달은 단순히 자동화를 “한 번 더” 한 경험이 아니었다.
내 사고방식이 바뀌었다.
“기술”보다 먼저 “책임”을 정의하게 됐다
예전에는 “어떤 툴을 쓸까”를 먼저 생각했다면,
이번에는 “누가 무엇을 책임져야 하는가”를 먼저 정의했다.
- CI는 스펙을 생성한다.
- 스펙 보관은 별도 컴포넌트가 책임진다.
- 변경 분석과 산출은 Job이 책임진다.
- 공유와 전달은 Bot이 책임진다.
기술 선택은 그 다음이었다.
“사람의 노력”이 아니라 “시스템의 이벤트”로 풀게 됐다
이전에는 “공유를 잘하자”, “엑셀을 잘 업데이트하자”, “배포 후 확인하자”처럼
사람의 주의력으로 해결하려 했다.
이번 경험 이후에는,
상태 변화를 시스템 이벤트로 정의하고 설계하는 방식으로 사고가 바뀌었다.
3) 자동화의 본질은 ‘편의’가 아니라 ‘재현성’이라는 걸 체감했다
자동화는 단순히 편해지는 게 아니라, “누가 하든 동일하게 재현되는 흐름”을 만든다.
특히 배포 이후는 변수가 많아서 사람이 개입할수록 누락과 오해가 생기기 쉽다.
이번 자동화는 “사람이 잘해야 되는 흐름”을
“시스템이 보장하는 흐름”으로 바꾸는 작업이었다.
다음 목표
이번 계기로,
각 팀이 반복적으로 수행하던 수작업 공유와 확인 과정을 시스템으로 자동화하고,
절약된 시간과 리소스를 사람이 직접 고민하고 판단해야 하는 문제에
투자할 수 있는 환경을 만드는 것이 목표입니다.
