연필로 그린 활주로: 고위험 배포를 위한 아날로그 사전 점검 설계하기
종이 체크리스트, 연필로 그린 활주로, 손으로 직접 하는 팀 의식을 통해, ‘배포’ 버튼을 누르기 훨씬 전부터 고위험 소프트웨어 배포의 신뢰성을 극적으로 높이는 방법을 다룹니다.
연필로 그린 활주로: 고위험 배포를 위한 아날로그 사전 점검 설계하기
조종사가 악천후 속에서 이륙하거나 짧은 활주로에서 뜰 때, “감”을 믿거나 계기 몇 개만 슬쩍 보고 이륙하지 않습니다. 반드시 사전 점검(preflight checklist)을 수행합니다. 체계적이고, 반복 가능하며, 일부러 지루하게 설계된 절차죠. 그 지루함 덕분에 비행기는 그렇게 자주 떨어지지 않습니다.
그런데 소프트웨어 세계, 특히 고위험 배포를 할 때 우리는 여전히 “아마 괜찮을 거야”라는 감과, 머릿속에 느슨하게만 있는 “이 정도면 되겠지” 수준의 모델에 많이 의존합니다.
이 글에서는 항공 분야의 사전 점검 규율을 고위험 배포에 적용하는 방법을 다룹니다. 의외의 조력자는 바로 연필과 종이입니다. 아날로그 “활주로”, 손으로 직접 하는 의식(ritual), Ansible 같은 도구를 활용한 스크립트형 점검, 그리고 체크리스트를 어떻게 살아 있는 문서로 유지·진화시킬지 살펴봅니다.
왜 사전 점검 체크리스트가 소프트웨어에도 필요한가
조종사의 사전 점검 체크리스트는 “권장사항”이 아니라 현실과 맺는 계약입니다.
- 모든 단계가 명시적이어야 합니다 — 기억에만 의존하지 않습니다.
- 모든 단계를 검증합니다 — 당연하다고 치지 않습니다.
- 모든 단계가 반복 가능합니다 — 매 비행마다 동일하게 수행됩니다.
스키마 마이그레이션, 대규모 리팩터링, 인프라 업그레이드, 리전 페일오버 같은 고위험 배포에도 똑같은 습관이 필요합니다.
- 체계적(Systematic): 충족되어야 할 명확하고 순서 있는 단계.
- 반복 가능(Repeatable): 매번 동일하거나, 개선된 점검.
- 가시적(Observable): 무엇을 언제 점검했는지 남는 산출물.
소프트웨어 세계의 “조종사 실수(pilot error)”는 보통 이런 식으로 나타납니다.
- 누군가 의존성을 하나 빼먹었다.
- 설정 플래그가 기본값(default)으로 그대로 남아 있다.
- 스테이징과 프로덕션 환경 사이에 숨어 있던 차이가 뒤늦게 드러난다.
사전 점검 체크리스트는 이런 것들이 사건이 되기 전에 막아 주는 방어막입니다.
아날로그 활주로: 왜 연필과 종이부터 시작해야 할까
멋진 대시보드와 자동화 스크립트부터 만들고 싶어지기 쉽습니다. 하지만 고위험 변경일수록 먼저 아날로그로 시작하는 편이 좋습니다.
“연필로 그린 활주로(pencil-drawn runway)”는 배포 경로를 눈에 보이게 표현한 물리적인 아티팩트입니다.
- 화이트보드나 큰 종이 한 장.
- 단계별로 나뉜 컬럼/레인: Preflight(사전 점검) → Taxi(활주로 이동) → Takeoff(이륙) → Climb(상승) → Cruise(순항) 등, 팀에 맞는 은유로 구성.
- 점검 항목, 의존성, 의사결정을 나타내는 포스트잇/인덱스 카드.
왜 먼저 아날로그여야 할까요?
- 이해를 강제합니다: 종이에 그려 보지 못한다면, 아직 변경 내용을 충분히 이해한 게 아닙니다.
- 일부러 속도를 늦춥니다: 각 단계를 손으로 하나씩 놓다 보면 빠뜨린 부분이 눈에 더 잘 띕니다.
- 복잡성이 눈에 보입니다: 점검 개수, 핸드오프, 가정이 얼마나 많은지 한눈에 들어옵니다.
- 협업을 초대합니다: 방에 있는 누구든 다가와서 질문하고, 카드를 옮기고, 의견을 낼 수 있습니다.
종이 활주로는 사전 점검 프로세스를 설계하는 디자인 공간이라고 생각하면 됩니다. 자동화는 나중에 해도 됩니다. 설계는 여기서 합니다.
사전 점검 설계하기: 이륙 전에 무엇이 ‘참’이어야 하는가
모든 고위험 배포에 공통으로 던져야 할 질문은 하나입니다.
이 변경을 배포하기 전에, 우리 시스템과 환경에 대해 무엇이 반드시 사실이어야 하는가?
이 질문을 그대로 체크리스트로 바꾸면 됩니다. 일반적인 범주는 다음과 같습니다.
1. 설정(Configuration) 준비 상태
- 피처 플래그가 정의·문서화되어 있고, 안전한 기본값으로 설정되어 있다.
- 핵심 설정값(타임아웃, 커넥션 제한, 스레드 풀 등)이 예상되는 신규 부하 패턴에 맞게 검증되었다.
- 시크릿·자격 증명이 존재하고, 유효하며, 필요하다면 교체(rotate)되었다.
- 스테이징과 프로덕션 간 **설정 드리프트(drift)**가 없는지(예: 설정 저장소, CMDB 등으로) 검증되었다.
2. 의존성(Dependency) 상태
- 모든 다운스트림 서비스에 접근 가능하고, 예상된 버전에서 동작하고 있다.
- 데이터 스토어(DB, 캐시, 큐 등)가 충분한 용량을 가지고 있고, 스키마/인덱스가 기대한 대로다.
- 서드파티 API에 대해 샌드박스 테스트와 쿼터(quota) 확인을 마쳤다.
- 내부 라이브러리·패키지가 지원되는 버전이며, 동작 특성이 잘 알려져 있다.
3. 환경(Environment) 일관성
- 스테이징이 프로덕션을 의미 있게 미러링하고 있다: 리소스 제한, 플래그, 데이터 형상 등.
- 네트워크 경로(방화벽, 시큐리티 그룹, 서비스 메시 정책 등)가 준비되어 있다.
- OS / 런타임 버전(Java, Python, Node 등)이 기대한 버전과 일치한다.
- 관측 가능성(Observability) 훅(메트릭, 로그, 트레이스)이 하위 환경에서 이미 연동 및 테스트되었다.
4. 운영(Operations) 준비 상태
- 롤백 계획이 문서화되어 있고, 실제로 테스트되었으며, 소요 시간 범위가 명시되어 있다.
- 온콜 인원이 확정되었고, 에스컬레이션 경로가 명확하다.
- 예상되는 장애 모드를 다루도록 **런북(runbook)**이 최신 상태다.
- 커뮤니케이션 플랜이 준비되었다: 누구에게, 언제, 어떤 채널로 알릴 것인지.
각 항목은 이진적이고 검증 가능한 문장이어야 합니다.
- 나쁜 예: “DB 괜찮아 보임.”
- 좋은 예: “
ordersDB 프라이머리 디스크 사용률 ≤ 70%, 리플리케이션 지연 < 1초이며, 이번 주 스테이징에서 페일오버 테스트 완료.”
종이에서 스크립트로: Ansible로 사전 점검 자동화하기
아날로그 활주로가 어느 정도 안정되면, 이를 스크립트형 사전 점검으로 옮길 수 있습니다.
Ansible 같은 도구는 다음과 같은 이유로 특히 유용합니다.
- 선언형(Declarative): 명령 나열이 아니라, 원하는 상태를 기술합니다.
- 멱등(Idempotent): 여러 번 실행해도 안전합니다.
- 감사 가능(Auditable): 플레이북 자체가 “어떻게 준비 상태를 검증하는지”를 보여 주는 버전 관리 아티팩트가 됩니다.
예시 패턴은 다음과 같습니다.
- 설정 점검: 설정 파일, 환경 변수, 템플릿 렌더링 결과를 검증하는 Ansible 태스크.
- 의존성 핑 테스트: TCP 연결, HTTP 헬스 엔드포인트, DB 연결성을 확인하는 모듈.
- 환경 검증: 커널 파라미터, 런타임 버전, 패키지 버전이 기준 프로파일과 일치하는지 확인.
- 관측 가능성 검증: 테스트 로그·메트릭이 모니터링 스택에서 실제로 보이는지 확인.
이렇게 해서 고위험 배포 전에 반드시 실행하는 preflight.yml 플레이북을 만들 수 있습니다.
ansible-playbook preflight.yml -e env=production
결과는 아주 단순해야 합니다.
- ✅ CLEAR TO DEPLOY: 모든 점검 통과.
- ⚠️ HOLD: 일부 점검 실패 — 해결 전까지 배포 중단.
즉, 아날로그 설계 단계에서 합의한 “사실이어야 할 것들”을 강제로 지키게 해 주는 기계화된 사전 점검을 만드는 셈입니다.
오베야(Obeya) 스타일 룸: 위험한 변경을 위한 촉각적 의식 만들기
린 제조(Lean Manufacturing)에서 차용할 개념이 하나 있습니다. 바로 오베야(Obeya), 팀이 한 공간에 모여 일을 시각화하고 실시간으로 조율하는 “큰 방”입니다.
고위험 배포를 위해서는 다음과 같은 “오베야 스타일” 환경을 구성해 볼 수 있습니다.
- 큰 벽 보드나 화이트보드를 활주로로 사용.
- 해당 배포에 특화된 인쇄/손글씨 체크리스트.
- 상태 레인: Not Started(미착수) → In Progress(진행 중) → Verified(검증 완료).
- 각 핵심 점검 항목에 명시적인 오너(owner) 지정.
사전 점검 세션 동안에는 다음과 같이 진행합니다.
- 활주로를 왼쪽에서 오른쪽으로 따라가며 진행합니다.
- 각 점검 항목을 소리 내어 읽습니다.
- 해당 항목이 스크립트 자동화, 수동 검증, 혹은 둘 다로 커버되는지 확인합니다.
- 실제 증거가 제시되었을 때만 항목을 손으로 “Verified(검증 완료)” 레인으로 옮깁니다.
이처럼 손으로 직접 움직이는 협업 의식은 다음을 가능하게 합니다.
- 모든 사람이 현재 준비 상태에 대해 동일한 그림을 공유하게 됩니다.
- 가정이나 빈틈을 일찍 드러냅니다.
- 위험에 대한 공동 소유감을 키웁니다.
이건 단순히 코드를 푸시하는 행위가 아니라, 이 활주로가 지금 이륙해도 안전한지 집단적으로 판단하는 과정이 됩니다.
살아 있는 문서: 사건·아찔한 상황 이후 체크리스트를 진화시키기
항공 분야의 체크리스트는 신성불가침한 문서가 아닙니다. **사고, 사건, 아찔한 상황(near miss)**이 발생할 때마다 계속해서 다듬어지고 업데이트됩니다.
배포 사전 점검 체크리스트도 똑같이 다뤄야 합니다.
- 실제 장애 이후에는 이렇게 묻습니다: “이 문제를 더 일찍 드러낼 수 있었던 체크가 무엇일까?”
- 아찔한 상황 이후에는 이렇게 묻습니다: “우리가 무시했거나 아예 보지 않았던 경고 신호는 무엇이었나?”
- 복잡하지만 매끄러웠던 배포 이후에는 이렇게 묻습니다: “어떤 체크가 가장 유용했나? 어떤 체크는 노이즈였나?”
구체적인 실천 방안은 다음과 같습니다.
- 사건 후 체크리스트 업데이트: 모든 인시던트 리뷰에 “체크리스트 추가/변경 사항” 섹션을 포함합니다.
- 사전 점검 문서 버전 관리: Git에 저장하고, 날짜와 배포 ID로 태깅합니다.
- 낡은 체크 제거: 더 이상 신호를 주지 못하는 항목은 주기적으로 정리합니다.
- 검증된 체크의 자동화 승격: 처음엔 수동으로 시작하되, 충분히 이해되고 안정적이면 자동화합니다.
시간이 지날수록 체크리스트는 단순한 추측 모음이 아니라, 현장에서 피와 땀으로 축적한 운영 지식의 집합으로 진화합니다.
모두 엮어 보기: 고위험 배포를 위한 예시 엔드 투 엔드 플로우
현실적인 전체 흐름 예시는 다음과 같습니다.
-
종이 위에서 활주로 설계하기
- 화이트보드에 배포 단계를 그립니다.
- 팀과 함께 리스크와 “참이어야 할 사실들”을 브레인스토밍합니다.
- 이를 구체적이고 이진적인 체크리스트 항목으로 바꿉니다.
-
각 점검을 수동/스크립트/혼합으로 태깅하기
- 수동(Manual): 사람의 판단이나 팀 간 합의가 필요한 항목.
- 스크립트(Scripted): Ansible 등으로 자동화 가능한 항목.
- 혼합(Both): 자동화 + 사람 확인이 모두 필요한 항목.
-
스크립트형 사전 점검 구현하기
ansible-playbook preflight.yml을 만듭니다.- 스테이징에서 여러 번 돌려 보며 오탐·미탐을 줄입니다.
- 이 플레이북 실행을 표준 배포 파이프라인에 포함시킵니다.
-
오베야 스타일 사전 점검 세션 진행하기
- 관련 개발자, SRE, PO, 온콜 인원을 한자리에 모읍니다.
- 체크리스트를 함께 훑고, 자동화 결과를 검토합니다.
- 핵심 항목 중 하나라도 충족되지 않으면 배포를 진행하지 않습니다.
-
명확한 GO/NO‑GO 결정과 함께 배포하기
- “Pilot in Command(최종 책임자)”를 한 명 지정해, NO를 말할 권한을 줍니다.
- GO 결정은 “느낌(vibes)”이 아니라, 체크리스트 완료 여부에 기반해야 합니다.
-
배포 후 리뷰·정제하기
- 예상 밖이었던 점, 빈틈이었던 부분을 정리합니다.
- 체크리스트와 자동화를 모두 업데이트합니다.
- 배운 내용을 다른 팀과 공유합니다.
결론: 지루함은 버그가 아니라 기능이다
고위험 배포가 완전히 안전해지는 일은 없겠지만, 체계적으로 더 안전하게 만들 수는 있습니다.
다음과 같은 방식으로요.
- 리스크를 눈에 보이게 만드는 연필로 그린 아날로그 활주로를 설계하고,
- Ansible 같은 도구로 포괄적인 스크립트형 사전 점검을 구축하고,
- 팀의 준비 상태를 맞추기 위한 손으로 직접 하는 협업 의식을 만들고,
- 모든 학습의 순간 이후에 체크리스트를 살아 있는 문서로 계속 진화시키면,
배포는 “잘 되길 바라는 마음”에 기대는 게 아니라, 훈련된 이륙 절차에 가까워집니다.
항공에서 체크리스트는 사람이나 기계를 맹신하기 위한 도구가 아닙니다. 둘 사이에 신뢰할 수 있는 파트너십을 만드는 구조입니다. 이와 같은 사고방식을 배포에도 적용하면, 중요한 순간에 시스템도, 팀도 훨씬 더 잘 날아오를 수 있습니다.