외주 개발자가 따라 할 서버 이관 지시서 RUNBOOK.md 를 여러 번 다시 썼는데 실행이 계속 실패했다. 다섯 번째에 성공하고 나서 되짚어 보니 실패 원인이 대상 쪽이 아니었다.
Table of contents
Open Table of contents
배경 — 다섯 번의 시도와 그 경위
첫 시도는 「nginx 설정을 옮긴다」처럼 지시가 모호해서 무엇을 하라는 것인지 불명확했다. 두 번째에 파일 경로와 명령으로 구체화해서 부분 성공을 얻었다. 세 번째에 팀의 docs/ 형식 규칙에 맞추려고 구조를 재편했다가 실패했다. 네 번째에 되돌렸는데 첫 번째와 같은 증상으로 다시 실패했다.
다섯 번째에 두 번째에서 통했던 요소를 온전히 복원하니 성공했다. 실패의 원인이 이관 대상의 성질이 아니라 내가 지시서를 다시 쓰는 과정에 있었다는 뜻이다.
원인 — 규칙을 지키려다 빠진 것
세 번째 시도에서 형식 규칙에 안 맞는 부분을 발견하고 파일 구성을 바꿨는데 그 과정에서 두 번째에 있던 요소 몇 개가 함께 빠졌다. 서버를 한 대씩 나눠 처리하라는 지시와 첫 명령 ssh 줄을 그대로 복사할 수 있게 적어 둔 부분이었다.
그것들이 왜 있었는지를 그 시점에는 기억하지 못했고 git log 에도 이유가 없었다. 두 번째 시도에서 실패를 겪고 넣은 장치인데 docs/ 규칙에 맞춰 재편하면서 정리 대상으로 보였다.
주의 — 되돌리면서 다시 빠진 것
네 번째에 되돌린다고 했지만 두 가지 방법이 있었는데 두 번째 판 파일을 cp 로 그대로 가져오는 것과 기억을 더듬어 다시 쓰는 것이다. 뒤쪽을 골랐고 그것이 실수였다. 이유는 형식 규칙에 맞춘 세 번째 판의 모양을 유지하고 싶어서였다. 다시 쓰는 과정에서 같은 요소가 또 빠졌고 그래서 첫 시도와 같은 실패 패턴이 나왔다.
같은 실패를 두 번 겪은 것인데 되돌리기를 복사가 아니라 재작성으로 한 것이 그 원인이었다. 이 시점에 개별 증상만 그때그때 고칠 뿐 접근 자체를 검토받지 않았다는 지적을 받았다.
조치 — 무엇이 동작하게 했는가
다섯 번째에서는 순서를 바꿔서 다시 쓰기 전에 이 판을 동작하게 만든 요소가 무엇인지를 먼저 CHECKLIST.md 에 목록으로 적었다. 서버별 분할 지시와 복사 가능한 첫 ssh 명령이 둘이다. 단계마다 - [ ] 로 진행을 표시하게 하는 구조와 journalctl 에서 필요한 줄만 grep 으로 발췌하는 패턴이 나머지 둘이다.
다시 쓴 뒤에 그 목록과 diff 로 하나씩 대조하니 셋째가 빠져 있었고 그것을 채우고 나서 성공했다. 대신 지시서를 고칠 때마다 대조하는 시간이 드는 것을 감수했다. 무엇이 동작하게 했는지를 적어 두지 않으면 재작성이 그것을 지운다는 사실을 대조로 확인한 셈이다.
검증 — 재작성의 표준 절차
이 대조를 예외적인 대응이 아니라 RUNBOOK.md 를 고칠 때의 표준 절차로 삼았다. 규칙 준수든 정리든 Markdown 에서 다른 형식으로의 변환이든 목적과 무관하게 이미 동작하는 부분을 건드릴 수 있기 때문이다.
함께 정한 것도 있는데 검토를 그 자리에서 못 받아도 포기하지 않고 다음 분기점에서 다시 요청하기로 했다. 착수 전에 그 영역의 기존 실패 기록 POSTMORTEM.md 를 먼저 읽는 것도 절차에 넣었다. 넘기기 전에 기계적인 부분을 bash -x 로 직접 실행해 확인하는 것도 넣었다.
정리
- 실패가 반복되면 원인이 대상이 아니라 나일 수 있다
- 동작하던 것을 다른 이유로 재구조화하면 검증된 부분이 떨어진다
- 되돌리기를 재작성으로 하면 같은 것이 다시 빠진다
- 무엇이 동작하게 했는지를 재작성 전에 목록으로 남긴다
- 재작성 뒤에 그 목록과 하나씩 대조한다
- 이 대조를 예외가 아니라 표준 절차로 삼는다
- 개별 증상만 고치면 접근의 문제가 안 드러난다
- 착수 전에 그 영역의 기존 실패 기록을 먼저 읽는다