Engineering

Terraform state lock 경합으로 배포가 멈췄을 때, 30분 안에 복구하는 운영 플레이북

Mike발행일 2026년 3월 30일읽는 시간 약 3

💡 Key Takeaways

  • state lock 장애는 강제 해제보다 실행 주체와 잠금 소유자 확인을 먼저 해야 2차 손상을 피할 수 있다.
  • 복구 순서는 락 식별, 단일 실행 보장, 검증 적용으로 고정해야 평균 복구 시간이 짧아진다.
  • 파이프라인 동시성 제어와 상태 파일 백엔드 관측 지표를 붙이면 같은 사고를 크게 줄일 수 있다.

1) 문제 정의: 배포 실패가 아니라 인프라 변경 파이프라인 정지 사고

월요일 오전 10시 12분, 운영 채널에 "프로덕션 배포가 17분째 Pending" 알림이 올라왔다. 애플리케이션 빌드는 끝났고 컨테이너 이미지도 정상 푸시됐지만, 인프라 단계에서 Terraform이 Error acquiring the state lock를 반복했다. 처음 담당자는 습관적으로 force-unlock부터 시도하려고 했지만, 직전 5분 사이 동일 워크스페이스를 만지는 잡이 세 개였다는 로그를 보고 멈췄다. 여기서 성급하게 잠금을 풀면 실제 적용 중인 다른 실행이 중간 상태로 끊기고 리소스 드리프트가 생길 수 있다. 우리 팀은 장애 문서 첫 줄에 "잠금 소유자, 시작 시각, 마지막 정상 apply"를 고정 기록하고, 한 명은 CI 실행 이력, 다른 한 명은 원격 백엔드 잠금 레코드를 병렬 확인했다. 특히 채널에 올라온 첫 메시지부터 담당자, 실행 링크, 워크스페이스 이름을 함께 남기게 하니 누락되는 맥락이 크게 줄었다. 이 역할 분리를 해두면 문제를 "Terraform 오류"로 뭉개지 않고 "동시 실행 제어 실패"라는 운영 사고로 바로 정의할 수 있다.

2) 판단 기준: 잠금 자체보다 잠금이 생긴 맥락을 먼저 본다

판단 기준은 네 가지였다. 첫째, 잠금 ID와 실행 주체가 지금 살아 있는 프로세스인지 확인한다. 둘째, 동일 워크스페이스에 대한 동시 실행이 허용되는 CI 설정이 있는지 점검한다. 셋째, 원격 상태 저장소(S3+DynamoDB, Terraform Cloud 등)의 지연이나 권한 오류가 잠금 해제 실패를 유발했는지 본다. 넷째, 최근 병합된 IaC 변경이 apply 시간을 급격히 늘려 잠금 점유 시간이 비정상적으로 커졌는지 확인한다. 실제 사고에서는 PR 두 개가 3분 간격으로 머지되며 main 파이프라인과 수동 재시도 파이프라인이 같은 워크스페이스를 동시에 잡았다. 여기에 야간에 추가한 데이터베이스 파라미터 변경이 11분 이상 걸리면서 잠금 점유가 길어졌고, 후속 실행이 타임아웃으로 연쇄 실패했다. 우리는 이 구간에서 담당자가 추측으로 움직이지 않도록 체크리스트에 "실행 프로세스 생존 확인 전 force-unlock 금지"를 굵게 표시해두었다. 중요한 점은 "누가 잠금을 잡고 있는지"가 명확하지 않으면 강제 해제 명령은 마지막 수단이어야 한다는 것이다.

3) 실행 절차: 30분 복구를 만든 고정 순서

복구는 실행 동결 -> 잠금 소유자 확인 -> 단일 재실행 -> 변경 검증 순서로 진행했다. 1단계에서 배포 트리거를 일시 중지하고 동일 워크스페이스로 들어오는 수동 실행을 막았다. 2단계에서 CI 실행 화면, 원격 백엔드 잠금 레코드, Terraform 로그의 실행 ID를 대조해 실제로 살아 있는 apply가 없는지 확인했다. 그다음에만 force-unlock를 1회 수행했고, 즉시 단일 파이프라인만 재개했다. 3단계에서는 plan 결과를 사람이 다시 확인해 파괴적 변경이 없는지 체크한 뒤 apply를 진행했다. 이때 롤백 경로를 남기려고 상태 파일 버전 스냅샷과 실행 로그를 동시에 보관했다. 또한 검증 담당자가 apply 중간에 콘솔 이벤트를 계속 기록해, 사후 회고에서 어떤 시점에 병목이 생겼는지 시간축으로 재구성할 수 있었다. 4단계에서 인프라 변경 후 애플리케이션 헬스체크, DB 연결, 메시지 큐 지연을 10분 관찰해 2차 장애가 없는지 확인했다. 결과적으로 장애 접수부터 정상화까지 31분이 걸렸고, 가장 큰 절감 포인트는 강제 해제를 늦춘 판단이었다.

4) 운영 체크리스트와 주의사항: 재발 방지는 동시성 설계에서 시작한다

사후 조치의 핵심은 도구 명령어가 아니라 파이프라인 정책이었다. 첫째, 워크스페이스별 동시 실행을 1로 고정하고, 이전 실행이 끝나기 전 재시도 버튼을 비활성화했다. 둘째, 상태 잠금 대기 시간이 5분을 넘으면 온콜 채널에 실행 ID와 잠금 소유자를 자동 전송하도록 알림을 붙였다. 셋째, 대형 인프라 변경(PR 템플릿에서 리소스 20개 이상 수정)은 별도 시간대에 직렬 실행하도록 규칙을 분리했다. 넷째, 런북에 "강제 해제 전 확인 6항목"을 넣어 누가 대응해도 동일한 판단 순서를 따르게 했다. 추가로 월 1회 워크스페이스별 잠금 이벤트를 리뷰해 반복 구간을 숫자로 확인하니, 팀이 감으로 느끼던 위험 구간이 실제 데이터로 드러났다. 마지막 주의사항은 잠금 충돌을 단순 대기 이슈로 취급하지 않는 것이다. 한 번의 잘못된 강제 해제로 생성/삭제가 어긋나면 복구 시간이 몇 시간으로 늘어난다. 그래서 우리는 lock 오류를 코드 버그가 아닌 운영 설계 결함으로 분류하고, 배포 승인 조건에 동시성 제어 점검을 포함했다.

함께 읽으면 좋은 글

Engineering

Kubernetes Secret 드리프트로 생긴 CrashLoopBackOff, 35분 안에 멈추는 복구 플레이북

2026-03-29
Engineering

백엔드 타임아웃 예산 설계 실전 플레이북: 장애를 줄이는 30분 판단 순서

2026-03-24

본문 작성/검수 원칙은 편집 원칙에서 확인할 수 있습니다.

← 목록으로 돌아가기