/인프라/Terraform state lock 에러 해결: force-unlock·DynamoDB 락 삭제
인프라Terraformstate lock

Terraform state lock 에러 해결: force-unlock·DynamoDB 락 삭제

Terraform "Error acquiring the state lock" 에러를 로그 판독표로 진단하고 force-unlock·DynamoDB 락 삭제로 안전 해제하는 법. lock-timeout과 CI 동시성 설정으로 재발까지 막는 복붙용 명령 모음.

Terraform state lock 에러 해결: force-unlock·DynamoDB 락 삭제

Terraform "Error acquiring the state lock" 해결법: force-unlock부터 DynamoDB 락 삭제까지

지금 파이프라인이 멈춰 있고 1초가 급하다면? 개념 설명 건너뛰고 4. 안전한 해제 절차로 바로 내려가세요. 다만 force-unlock을 치기 전에 2번 판독표 한 줄만 보고 가는 걸 강력히 권합니다. 잘못 풀면 state가 깨집니다.

terraform apply를 돌렸는데 빨간 글씨로 Error acquiring the state lock이 떴다면, 누군가(혹은 다른 CI 잡, 혹은 30분 전에 Ctrl+C로 죽인 나 자신)가 같은 state에 락을 걸어둔 상태입니다. 무작정 force-unlock을 치는 게 가장 흔한 실수예요. 떠 있는 락이 진짜 살아있는 작업의 락이면 강제 해제 순간 두 프로세스가 동시에 state를 쓰면서 인프라가 꼬입니다.

이 글은 에러 로그를 5초 만에 판독 → 원인 분기 → 안전 해제 → 재발 방지까지, 복붙 가능한 명령과 표만으로 끝냅니다.

1. 에러 원문 로그 판독표 — 5초 진단

Terraform이 던지는 락 에러는 보통 이렇게 생겼습니다.

CODE
Error: Error acquiring the state lock

Error message: ConditionalCheckFailedException: The conditional
request failed
Lock Info:
  ID:        a1b2c3d4-5e6f-7890-abcd-ef1234567890
  Path:      my-bucket/env/prod/terraform.tfstate
  Operation: OperationTypeApply
  Who:       user@hostname
  Version:   1.7.5
  Created:   2026-06-14 09:12:33.123456 +0000 UTC
  Info:

이 블록을 필드별로 분해해 읽으면 답이 거의 보입니다.

필드값 예시무엇을 알려주나 / 판단 기준
IDa1b2c3d4-...567890force-unlock에 그대로 넣을 락 ID. 이 값이 명령의 인자가 됩니다.
Pathmy-bucket/env/prod/terraform.tfstate락이 걸린 S3 키 경로. 어느 환경(prod/stg)이 막혔는지 확인. DynamoDB 직접 조회 시 LockID로도 사용.
OperationOperationTypeApplyapply 도중인지 plan 도중인지. apply에서 끊겼다면 state 일부가 이미 갱신됐을 수 있어 더 신중하게.
Whouser@hostname누가/어느 CI 러너가 잡았나. 본인 호스트명이면 내 이전 실행, runner-xxx면 CI 잡. 모르는 동료면 먼저 물어보세요.
Created2026-06-14 09:12:33 UTC언제 잡혔나. 지금 시각과 차이가 크면(예: 30분 전) 비정상 종료로 남은 유령 락일 확률이 높습니다.
Version1.7.5락을 건 Terraform 버전. 팀 내 버전 불일치 디버깅용 참고값.

핵심은 Who + Created 조합입니다. "내 호스트명 + 한참 전 시각"이면 거의 유령 락이고, "다른 CI 러너 + 방금 전 시각"이면 실제 실행 중인 작업이니 건드리지 말고 기다려야 합니다.

2. 원인별 분기 진단 — 내 락은 유령인가, 살아있나

판독표로 좁혔다면 아래 5가지 중 하나에 해당합니다.

원인대표 증상1차 확인조치
이전 실행 비정상 종료(Ctrl+C, OOM kill)Who가 본인, Created가 오래됨Created 시각이 현재와 크게 차이force-unlock 안전하게 가능
CI 동시 실행 충돌Who가 CI 러너, 다른 잡이 동시 실행 중파이프라인에서 같은 워크플로 동시 실행 여부종료 대기 후 동시성 제어 도입
네트워크 끊김apply 중 연결 끊긴 뒤 멈춤러너/로컬 로그에 timeout·connection reset러너 죽었음 확인 후 락 해제 + 재시도
DynamoDB 권한 부족AccessDeniedException 동반IAM 정책 점검dynamodb:GetItem/PutItem/DeleteItem 권한 부여
S3 backend 설정 오류dynamodb_table 누락·오타backend 블록 검증설정 수정 후 terraform init -reconfigure

현장 경험 한 줄: 제가 운영하던 팀에서 락 에러의 80%는 첫 번째와 두 번째였습니다. 새벽에 OOM으로 죽은 잡이 남긴 유령 락, 그리고 같은 main 브랜치 머지가 연달아 트리거되며 두 apply가 겹친 경우죠. 그래서 CI 동시성 제어 한 줄(5번)이 사실상 가장 가성비 좋은 근본 대책이었습니다.

3. 살아있는 락인지 먼저 확인하기

force-unlock 전에 Who의 러너/사람이 실제로 돌고 있는지 반드시 교차 확인하세요.

  • CI 러너라면: GitHub Actions / GitLab에서 해당 잡이 아직 running인지 확인. running이면 절대 풀지 말고 끝나길 대기.
  • 본인 로컬이라면: 다른 터미널에 살아있는 terraform 프로세스가 있는지 확인.
Bash
ps aux | grep terraform | grep -v grep

프로세스가 없고 CI 잡도 모두 종료 상태라면, 그 락은 유령입니다. 안심하고 4번으로.

4. 안전한 해제 절차 (복붙용)

4-1. 1순위: terraform force-unlock

판독표에서 본 ID을 그대로 넣습니다.

Bash
# 반드시 다른 사람/CI가 실행 중이 아님을 확인한 뒤!
terraform force-unlock a1b2c3d4-5e6f-7890-abcd-ef1234567890

# 자동화/비대화형(CI) 환경에서 확인 프롬프트 없이
terraform force-unlock -force a1b2c3d4-5e6f-7890-abcd-ef1234567890

⚠️ 위험성 경고 실제 실행 중인 작업의 락을 강제 해제하면 두 프로세스가 동시에 state를 쓰면서 state 파일이 손상되거나, 리소스가 중복 생성/삭제될 수 있습니다. force-unlock은 "그 작업이 확실히 죽었다"는 확신이 있을 때만 사용하세요. apply 도중 끊긴 락이라면 해제 후 반드시 terraform plan으로 실제 상태와의 드리프트부터 점검합니다.

4-2. 최후 수단: DynamoDB 락 테이블 직접 삭제

force-unlock이 ID 불일치나 backend 깨짐으로 안 먹힐 때, DynamoDB 항목을 직접 건드립니다.

Bash
# 현재 락 항목 조회 (LockID = "<bucket>/<key>" 형식)
aws dynamodb get-item \
  --table-name terraform-locks \
  --key '{"LockID":{"S":"my-bucket/env/prod/terraform.tfstate"}}'

# 락 항목 강제 삭제 (force-unlock이 안 먹힐 때 최후 수단)
aws dynamodb delete-item \
  --table-name terraform-locks \
  --key '{"LockID":{"S":"my-bucket/env/prod/terraform.tfstate"}}'

-md5 접미사 주의: DynamoDB에는 보통 두 종류의 항목이 들어 있습니다.

  • my-bucket/env/prod/terraform.tfstate실제 락 항목. 삭제 대상은 이것.
  • my-bucket/env/prod/terraform.tfstate-md5state 파일의 체크섬(다이제스트) 항목. 무결성 검증용이라 삭제하면 안 됩니다. 이걸 지우면 다음 실행에서 state 검증 경고가 뜰 수 있어요.

즉 락만 풀고 싶다면 -md5붙지 않은 LockID만 delete-item 하세요.

5. 재발 방지 체크리스트

한 번 겪었으면 다시는 안 겪게 막는 게 진짜 실력입니다.

5-1. lock-timeout으로 즉시 실패 대신 대기

Bash
# 락이 잡혀 있으면 바로 실패하지 말고 120초까지 재시도하며 대기
terraform apply -lock-timeout=120s

짧게 겹치는 동시 실행은 이 한 줄로 자연스럽게 줄을 서게 됩니다.

5-2. backend 설정 표준화

HCL
terraform {
  backend "s3" {
    bucket         = "my-bucket"
    key            = "env/prod/terraform.tfstate"
    region         = "ap-northeast-2"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

dynamodb_table을 빼먹으면 애초에 락 자체가 안 걸려 동시 쓰기 사고가 납니다. 환경별 key는 반드시 분리하세요.

5-3. CI 동시성 제어 — 가장 효과적인 근본 대책

GitHub Actions — 같은 워크플로의 중복 실행을 직렬화:

YAML
concurrency:
  group: terraform-prod
  cancel-in-progress: false   # 진행 중 잡을 죽이지 말고 줄 세우기

GitLab CIresource_group으로 동일 리소스 잡 직렬화:

YAML
deploy_prod:
  stage: deploy
  resource_group: terraform-prod
  script:
    - terraform apply -auto-approve -lock-timeout=120s

이 두 줄이면 "main 연속 머지로 apply 두 개가 겹쳐 락 충돌" 시나리오가 사라집니다.

5-4. 참고: DynamoDB 없는 S3 native locking

Terraform 1.10+ 부터는 use_lockfile = true 옵션으로 DynamoDB 테이블 없이 S3 자체에 락 파일을 두는 방식이 가능해졌습니다.

HCL
terraform {
  backend "s3" {
    bucket       = "my-bucket"
    key          = "env/prod/terraform.tfstate"
    region       = "ap-northeast-2"
    use_lockfile = true   # DynamoDB 불필요
    encrypt      = true
  }
}
구분DynamoDB 방식S3 native(use_lockfile)
추가 리소스DynamoDB 테이블 필요S3 버킷만으로 가능
적용 버전모든 버전Terraform 1.10+
락 해제force-unlock / delete-itemforce-unlock / S3 .tflock 객체 삭제

📌 OpenTofu 사용자도 위 terraform force-unlocktofu force-unlock으로 바꾸면 동일하게 적용됩니다. DynamoDB/S3 CLI 명령은 그대로예요.


자주 묻는 질문 (FAQ)

Q. force-unlock을 했는데도 또 "Error acquiring the state lock"이 떠요. A. 두 가지를 의심하세요. ① 다른 CI 잡이 여전히 실행 중이라 락을 재생성하고 있는 경우 — 잡을 먼저 멈추세요. ② backend ID 불일치로 force-unlock이 실제 항목을 못 지운 경우 — 4-2의 aws dynamodb get-item으로 LockID를 직접 확인하고 delete-item 하세요.

Q. DynamoDB에서 -md5가 붙은 항목도 같이 지워야 하나요? A. 아니요. -md5는 state 무결성 체크섬이라 지우면 안 됩니다. 락 해제는 -md5가 붙지 않은 LockID 항목만 삭제하면 됩니다.

Q. apply 도중 끊겨서 락을 풀었는데, 인프라 상태가 불안합니다. 뭘 먼저 해야 하나요? A. 해제 직후 곧바로 terraform plan을 돌려 실제 리소스와 state의 드리프트를 확인하세요. apply가 절반만 반영됐을 수 있으므로, plan 결과를 검토한 뒤에만 재apply 하는 것이 안전합니다.

✦ ✦ ✦
편집 검토 · Editorial Review

이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.

작성 · Content Reviewer·검토 · 사람 편집자·발행 · 2026년 6월 14일

댓글

불러오는 중...