Terraform S3 네이티브 락 — DynamoDB 제거

클라우드·인프라3분조회

Terraform state 를 S3 에 두면서, 동시에 두 명이 apply 하는 걸 막으려고 DynamoDB 락 테이블을 함께 썼습니다. 오래된 표준 구성입니다.

이 DynamoDB 를 걷어냈습니다.

락에 DynamoDB 테이블이 필요했던 이유

S3 는 오랫동안 “이 파일이 이미 있으면 쓰지 마라” 를 원자적으로 보장하지 못했습니다. 그래서 락을 S3 로 구현할 수 없었습니다.

DynamoDB 는 조건부 쓰기가 되니까 락을 여기에 뒀습니다. apply 를 시작할 때 락 항목을 만들고, 이미 있으면 다른 사람이 작업 중이라는 뜻이라 멈춥니다. 끝나면 지웁니다. 상태 저장은 S3, 동시 실행 차단은 DynamoDB 로 나뉘어 있었던 겁니다.

S3 conditional write로 테이블 불필요

S3 에 If-None-Match 조건부 쓰기가 들어왔습니다. “같은 키가 이미 있으면 실패” 를 S3 가 직접 보장합니다. DynamoDB 가 하던 일을 S3 가 하게 된 겁니다.

OpenTofu 1.10, Terraform 1.11 부터 이걸 쓰는 use_lockfile 옵션이 생겼습니다. 락 파일(.tflock)을 S3 에 conditional write 로 만들어서 동시 apply 를 막습니다. 별도 체크섬 저장도 필요 없습니다. conditional write 자체가 무결성을 보장합니다.

변경은 두 줄

# 전 — DynamoDB
backend "s3" {
  bucket         = "my-state-bucket"
  key            = "terraform.tfstate"
  region         = "ap-northeast-2"
  encrypt        = true
  dynamodb_table = "terraform-locks"   # 제거
}

# 후 — S3 native locking
backend "s3" {
  bucket       = "my-state-bucket"
  key          = "terraform.tfstate"
  region       = "ap-northeast-2"
  encrypt      = true
  use_lockfile = true                  # 추가
}

바꾼 뒤 tofu init -reconfigure 를 한 번 돌립니다. Terragrunt 환경이면 terragrunt plan 이 init 을 자동으로 처리해서 따로 안 해도 되는 경우가 많습니다.

전환 순간의 주의점

DynamoDB 락과 S3 락은 서로 다른 메커니즘입니다. 전환하는 그 순간에 다른 파이프라인이 아직 DynamoDB 락으로 apply 중이면, 두 락이 서로를 못 봐서 동시 실행이 될 수 있습니다.

apply 가 도는 프로세스가 없는 상태에서 바꾸면 문제없습니다. CI 파이프라인이 있으면 잠깐 멈추고 전환하는 게 안전합니다.

버전 요구사항

도구 지원 비고
OpenTofu 1.10+ DynamoDB 방식도 계속 유지
Terraform 1.11 GA (1.10 experimental) DynamoDB 인자 deprecated

OpenTofu 는 DynamoDB 방식을 없앨 계획이 없어서 급하게 바꿀 필요는 없습니다. 다만 새로 구성하는 백엔드라면 테이블을 하나 덜 만드는 쪽이 낫습니다. 관리할 리소스가 줄고, 락 때문에 IAM 권한을 DynamoDB 로 넓힐 일도 없어집니다.

참고

  1. 불러오는 중