Terraform S3 네이티브 락 — DynamoDB 제거

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

Terraform 은 지금 인프라가 어떤 상태인지를 state 파일에 적어 두고, apply 할 때 그 파일과 실제를 비교해 차이만 반영합니다. 이 파일이 로컬에 있으면 다른 사람은 볼 수 없으니 대개 S3 같은 원격에 올려 두고 같이 씁니다.

같이 쓰다 보면 두 명이 동시에 apply 하는 상황이 생기는데, 둘 다 같은 state 를 읽고 각자 고쳐 쓰면 나중에 쓴 쪽이 앞사람 작업을 덮어씁니다. 그래서 apply 하는 동안 다른 사람이 못 들어오게 락을 겁니다.

그 락은 DynamoDB 테이블에 뒀습니다. Terraform 뿐 아니라 라이선스가 바뀌면서 갈라져 나온 오픈소스 포크 OpenTofu 도 같은 구성을 쓰고, 오래전부터 표준으로 통하던 구성이라 별생각 없이 따라 만든 면도 있습니다.

state 파일 하나 지키자고 테이블을 따로 두는 게 계속 걸렸는데, OpenTofu 1.10 과 Terraform 1.11 부터 S3 만으로 락이 되면서 이 테이블을 걷어냈습니다.

락에 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 를 막는 방식입니다. 락 파일 하나로 끝나니 DynamoDB 테이블 자체가 필요 없어지고, 거기 같이 두던 state 다이제스트도 함께 사라집니다.

백엔드 설정 변경

# 전 — 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. 불러오는 중