LGTM != Production Ready: 왜 당신의 CI 파이프라인은 가장 중요한 단계를 놓치고 있는가
Source: Dev.to

Source:
개요
우리는 구문 검사를 위한 린터와 보안을 위한 스캐너를 가지고 있습니다. 이제 “이게 새벽 3시에 나를 깨울까?”를 검사하는 린팅을 시작할 차례입니다.
당신은 풀 리퀘스트를 제출합니다. CI가 초록색으로 통과합니다. 동료들이 리뷰하고 “LGTM!”이라고 댓글을 달죠. 코드가 머지되고 배포됩니다.
3일 후, 새벽 3시 17분에 PagerDuty가 울립니다.
근본 원인은 구문 오류가 아니었습니다. 단위 테스트로 잡을 수 있는 논리 버그도 아니었습니다. 그것은 미묘한 문제였는데, 바로 타임아웃 설정이 누락된 HTTP 클라이언트가 다운스트림 서비스가 일시적으로 멈췄을 때 연쇄적인 실패를 일으킨 것이었습니다.
“시니어 직관” 격차
PR 검토에서 누락된 타임아웃을 놓친 이유는?
- 일반적인 코드 리뷰는 보통 코드 스타일, 논리 정확성, 유지보수성에 초점을 맞춥니다.
- 일반적인 정적 분석 도구는 구문 오류나 명백한 보안 결함을 잡아냅니다.
아무도 운영 성숙도를 적극적으로 grep하지 않는다. 보통 이러한 잠재적 실패 모드를 포착하는 것은 “시니어 엔지니어 직관”에 의존한다—오랜 기간 온‑콜로 깨워진 전투 경험이 있는 SRE가 개발하는 스파이더‑센스다. 그들은 코드를 한눈에 보고 즉시 생각한다: “백오프 재시도 로직은 어디에 있지?” 혹은 “이 검증되지 않은 환경 변수는 언젠가 부팅을 망가뜨릴 거야.”
문제는 시니어 직관은 확장되지 않는다는 점이다. 최고의 SRE를 복제해서 모든 PR을 검토하게 할 수는 없다.
체크리스트의 실패
많은 조직이 이를 “프로덕션 준비 체크리스트”로 해결하려고 합니다 — “실패 도메인을 고려했나요?”와 같은 수십 개의 질문이 적힌 먼지가 쌓인 Confluence 페이지입니다.
솔직히 말하자면, 아무도 이것을 사용하지 않습니다. 수동적이고 지루하며 개발 라이프사이클의 마지막에 수행됩니다(아키텍처를 변경하기엔 너무 늦음). 보통은 경영진을 달래기 위한 “체크박스 연극”에 불과합니다.
자동화되지 않으면 존재하지 않는 것입니다.
“Operability”를 왼쪽으로 이동하기
운영 요구사항을 코드 스타일과 동일하게 다뤄야 합니다. gofmt가 실패하면 병합할 수 없듯이, 코드에 잠재적인 운영 위험이 포함되어 있으면 병합해서는 안 됩니다.
저는 그 “시니어 엔지니어 직관”을 실행 가능한 형태로 구체화한 도구가 필요했습니다—변수 이름에는 신경 쓰지 않지만, 애플리케이션이 부분적인 네트워크 장애를 견딜 수 있는지에 대해서는 깊이 신경 쓰는 스캐너 말이죠.
제가 필요에 맞는 도구를 찾지 못해 직접 만들었습니다.
Production‑Readiness 소개
Production‑Readiness는 운영상의 사각지대를 프로덕션에 도달하기 전에 감지하도록 설계된 오픈소스, 의견이 반영된 스캐너입니다.
- Prometheus나 Datadog을 대체하는 것이 아닙니다.
- 코드에서는 “올바른” 것으로 보이지만 프로덕션에서 화재를 일으키는 패턴을 찾아내는 사전 점검입니다.
실제로 무엇을 잡아내나요?
표준 린터와 달리, 이 도구는 의미론적 운영 패턴을 찾습니다. 다음은 일반적인 정규식 grep으로 잡기 어려운 규칙 몇 가지 예시입니다:
1. “걸려있는 클라이언트” 함정
- 위험: 무한 타임아웃으로 HTTP 클라이언트를 인스턴스화하면 모든 스레드/고루틴이 점유되어 결국 서비스가 크래시됩니다.
- 해결: 스캐너는 명시적인 타임아웃 없이 초기화된 클라이언트를 표시합니다.
2. 우아한 종료 누락
- 위험: 쿠버네티스가 파드를 스케일 다운하면
SIGTERM을 보냅니다. 애플리케이션이 이를 처리하지 않고 진행 중인 요청을 완료하지 않으면, 매 배포 또는 자동 스케일 이벤트마다 사용자 트래픽이 손실됩니다. - 해결: 스캐너는 시그널 처리 연결을 검사합니다.
3. 검증되지 않은 구성
- 위험: 애플리케이션은 시작을 위해
API_KEY환경 변수가 필요합니다. 배포했지만 새로운 환경에 변수가 없어서 크래시 루프에 빠집니다. - 해결: 스캐너는 중요한 구성 입력에 검증 로직이 연결되어 있는지 확인합니다.
행동으로 보기
이 도구는 Go로 작성되었으며, CI 파이프라인에 넣어 사용할 수 있는 단일 바이너리로 패키징됩니다.
$ pr scan ./my-microservice
운영 위험을 우선순위별로 정리한 보고서를 생성합니다.

결론
“작동하는 코드”와 “프로덕션에서 안정적으로 실행되는 코드” 사이의 격차는 엄청납니다. 우리는 그 격차를 메우기 위해 희망과 수동 체크리스트에 의존하는 것을 멈춰야 합니다.
운영 안티패턴을 자동으로 감지함으로써 더 빠르게 배포하고, 무엇보다도 더 편안하게 잠잘 수 있습니다.
이 프로젝트는 오픈소스이며, 소프트웨어를 “프로덕션‑준비 완료”로 만드는 규칙을 정의하기 시작한 단계에 불과합니다.
프로덕션에서 “사소한” 설정 실수로 고통을 겪어본 적이 있다면, 한 번 사용해 보세요.
👉 GitHub에서 저장소에 ⭐ 표시하기