Terraform State 락(Lock) 해제 및 CI/CD 환경 원격 백엔드 충돌 시 안전한 복구 전략

GitHub Actions나 Jenkins 같은 CI/CD 파이프라인에서 배포를 돌렸는데, 갑자기 "Error: Error acquiring the state lock" 메시지가 뜨며 멈춘 적이 있을 거예요. 동료와 동시에 terraform apply를 실행했거나, 이전 작업이 비정상적으로 종료되어 락이 풀리지 않았을 때 발생하는 전형적인 문제죠.

이 글에서는 인프라 상태 파일(State file)을 망가뜨리지 않고, DynamoDB에 걸린 락을 안전하게 해제하여 배포 파이프라인을 정상화하는 실무 전략을 공유해요.

TL;DR — Terraform State 락 충돌은 terraform force-unlock [LockID] 명령어로 해결하며, DynamoDB를 백엔드로 구성해 다중 작업자의 동시 수정을 원천 차단하는 것이 핵심이에요.

1. Terraform State 락이란 무엇인가

💡 비유로 이해하기: 도서관에서 누군가 책을 빌려 가기 위해 대출대에서 확인 중일 때는, 그 뒤에 선 사람이 동시에 그 책을 가져갈 수 없도록 '처리 중' 푯말을 세워두는 것과 같아요.

Terraform은 인프라의 현재 상태를 terraform.tfstate라는 파일에 저장해요. 현재 최신 안정 버전인 v1.11.x 기준, 여러 명이 동시에 이 파일을 수정하면 인프라 정보가 꼬여서 실제 자원과 상태 파일이 불일치하는 재앙이 발생할 수 있어요. 이를 막기 위해 한 작업자가 수정 중일 때 파일에 자물쇠를 채우는 기능이 바로 'State Lock'이에요.

원격 백엔드로 AWS S3를 사용할 때, S3 자체는 파일 잠금 기능을 제공하지 않기에 DynamoDB라는 별도의 데이터베이스를 활용해 누가 현재 자물쇠 열쇠를 가지고 있는지 기록하게 돼요.

2. 실무에서 락 충돌이 발생하는 3가지 상황

개발자가 의도치 않게 락 에러를 마주하는 시나리오는 보통 다음과 같아요.

  • CI/CD 파이프라인 중복 실행: 동일한 테라폼 코드를 사용하는 두 개의 PR이 동시에 Merge되어 워크플로우가 겹칠 때 발생해요.
  • 비정상적인 프로세스 종료: terraform apply 도중 네트워크 문제나 로컬 PC의 강제 종료로 인해 "락 해제(Unlock)" 단계까지 도달하지 못한 경우예요.
  • 타임아웃 발생: 대규모 인프라 변경 시 클라우드 프로바이더의 응답이 늦어져 테라폼 프로세스가 응답 없음 상태로 빠질 때 나타나요.

3. 단계별 구현 가이드 — DynamoDB 활용하는 법

먼저 원격 백엔드를 안전하게 구성한 뒤, 문제가 생겼을 때 해제하는 흐름을 살펴볼게요.

Step 1. S3와 DynamoDB 백엔드 설정

Terraform 설정 파일(backend.tf)에 락 관리를 위한 테이블을 명시해야 해요.


terraform {
backend "s3" {
bucket         = "my-terraform-state-bucket"
key            = "prod/terraform.tfstate"
region         = "ap-northeast-2"
# 락 관리를 위한 DynamoDB 테이블 이름
dynamodb_table = "terraform-lock-table"
encrypt        = true
}
}

Step 2. 락 상태 확인 및 Lock ID 추출

에러 메시지를 보면 ID: e56c7a8b-xxxx 형태의 문자열이 보여요. 이것이 DynamoDB에 기록된 현재 락의 고유 식별자예요. 이 ID가 있어야 강제로 잠금을 풀 수 있어요.



테라폼 실행 시 에러 메시지 예시
Error: Error acquiring the state lock
Lock Info:
ID:        e56c7a8b-f231-4122-8d11-92341234
Operation: OperationTypeApply
Who:       jenkins@build-server

Step 3. 강제 락 해제 실행

누가 작업을 하고 있는지 확인한 뒤(동료에게 물어보는 게 가장 안전해요), 확실히 프로세스가 죽었다면 아래 명령어를 실행해요.



추출한 Lock ID를 넣어 실행해요.
terraform force-unlock e56c7a8b-f231-4122-8d11-92341234

4. S3 전용 백엔드 vs S3 + DynamoDB 비교

단순히 S3에 상태 파일을 저장하는 것과 DynamoDB를 병행하는 것은 협업 생산성 면에서 큰 차이가 있어요.

비교 기준 S3 Only S3 + DynamoDB
동시 수정 방지불가능 (최종 쓴 파일이 덮어씀)가능 (락 획득 필수)
데이터 정합성낮음 (State 손상 위험)매우 높음
협업 적합도개인 프로젝트용엔터프라이즈/팀 단위 필수
설정 복잡도낮음보통 (테이블 생성 필요)

실무라면 인프라 규모와 관계없이 S3 + DynamoDB 조합을 선택하는 것이 정신 건강에 이로워요.

5. 주의사항 및 트러블슈팅

⚠️ 가장 자주 하는 실수: 실제 진행 중인 작업을 확인하지 않고 force-unlock을 때리는 경우예요. 자원이 생성되는 도중에 락을 풀고 다른 사람이 접근하면, 중복 자원이 생성되거나 일부 자원이 '좀비' 상태가 되어 삭제가 불가능해질 수 있어요.

강제 해제 전에는 반드시 CI/CD 대시보드에서 해당 워크플로우가 '취소' 또는 '실패' 상태인지 먼저 확인해야 해요.

에러 메시지별 해결법



상황: DynamoDB 테이블 권한 부족
AccessDeniedException: User is not authorized to perform: dynamodb:PutItem
해결: 해당 IAM 사용자/역할에 DynamoDB FullAccess 또는 특정 테이블 권한을 부여하세요.

6. 실전에서 바로 쓰는 팁

인프라 운영의 안정성을 높이는 소소하지만 강력한 팁들이에요.

첫째, DynamoDB 테이블의 Partition Key는 반드시 LockID(문자열)로 설정해야 해요. 이름이 다르면 테라폼이 락 정보를 읽지 못해요.

둘째, CI/CD 환경이라면 Lock Timeout 옵션을 활용하세요. terraform plan -lock-timeout=300s 처럼 설정하면 다른 작업이 끝날 때까지 5분간 기다렸다가 시도하므로 불필요한 실패를 줄일 수 있어요.

📌 핵심 요약

  • Terraform State 락은 데이터 손상을 막는 안전장치이며, 협업 시 필수예요.
  • 락 충돌 시 에러 메시지에서 Lock ID를 확인한 후 force-unlock 명령어를 사용해요.
  • AWS 환경에서는 S3와 DynamoDB를 조합해 견고한 백엔드 잠금 구조를 만들어야 해요.

Frequently Asked Questions

Q. Terraform State 락이 걸리는 근본적인 이유는 무엇인가요?

A. 두 명 이상의 사용자가 동시에 상태 파일을 수정하여 데이터가 손상되는 'Race Condition'을 방지하기 위함이에요.

Q. force-unlock 명령어 사용 시 위험성은 없나요?

A. 실제로 실행 중인 프로세스가 있을 때 강제로 풀면 상태 파일과 실제 인프라가 불일치하게 될 위험이 커요.

Q. DynamoDB를 사용해도 락 충돌이 발생하는 이유는 무엇인가요?

A. 이전 작업이 비정상 종료되어 DynamoDB 테이블에 락 레코드가 삭제되지 않고 남아있기 때문이에요.

OlderNewest

Post a Comment